Merge pull request #124 from kanflo/rboot-merge
Updated rboot to #75ca33b including the flash write bug.
This commit is contained in:
commit
736e790e80
9 changed files with 505 additions and 130 deletions
|
@ -14,13 +14,15 @@
|
||||||
#include "ssid_config.h"
|
#include "ssid_config.h"
|
||||||
|
|
||||||
#include "ota-tftp.h"
|
#include "ota-tftp.h"
|
||||||
#include "rboot-ota.h"
|
#include "rboot-integration.h"
|
||||||
|
#include "rboot.h"
|
||||||
|
#include "rboot-api.h"
|
||||||
|
|
||||||
void user_init(void)
|
void user_init(void)
|
||||||
{
|
{
|
||||||
uart_set_baud(0, 115200);
|
uart_set_baud(0, 115200);
|
||||||
|
|
||||||
rboot_config_t conf = rboot_get_config();
|
rboot_config conf = rboot_get_config();
|
||||||
printf("\r\n\r\nOTA Basic demo.\r\nCurrently running on flash slot %d / %d.\r\n\r\n",
|
printf("\r\n\r\nOTA Basic demo.\r\nCurrently running on flash slot %d / %d.\r\n\r\n",
|
||||||
conf.current_rom, conf.count);
|
conf.current_rom, conf.count);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
#include <espressif/esp_system.h>
|
#include <espressif/esp_system.h>
|
||||||
|
|
||||||
#include "ota-tftp.h"
|
#include "ota-tftp.h"
|
||||||
#include "rboot-ota.h"
|
#include "rboot.h"
|
||||||
|
#include "rboot-api.h"
|
||||||
|
|
||||||
#define TFTP_FIRMWARE_FILE "firmware.bin"
|
#define TFTP_FIRMWARE_FILE "firmware.bin"
|
||||||
#define TFTP_OCTET_MODE "octet" /* non-case-sensitive */
|
#define TFTP_OCTET_MODE "octet" /* non-case-sensitive */
|
||||||
|
@ -112,7 +113,7 @@ static void tftp_task(void *listen_port)
|
||||||
netbuf_delete(netbuf);
|
netbuf_delete(netbuf);
|
||||||
|
|
||||||
/* Find next free slot - this requires flash unmapping so best done when no packets in flight */
|
/* Find next free slot - this requires flash unmapping so best done when no packets in flight */
|
||||||
rboot_config_t conf;
|
rboot_config conf;
|
||||||
conf = rboot_get_config();
|
conf = rboot_get_config();
|
||||||
int slot = (conf.current_rom + 1) % conf.count;
|
int slot = (conf.current_rom + 1) % conf.count;
|
||||||
|
|
||||||
|
|
214
extras/rboot-ota/rboot-api.c
Normal file
214
extras/rboot-ota/rboot-api.c
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot OTA and config API for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
// OTA code based on SDK sample from Espressif.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <rboot.h>
|
||||||
|
#include <string.h>
|
||||||
|
//#include <c_types.h>
|
||||||
|
//#include <spi_flash.h>
|
||||||
|
|
||||||
|
// detect rtos sdk (not ideal method!)
|
||||||
|
#ifdef IRAM_ATTR
|
||||||
|
#define os_free(s) vPortFree(s)
|
||||||
|
#define os_malloc(s) pvPortMalloc(s)
|
||||||
|
#else
|
||||||
|
#include <mem.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rboot-api.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOT_CONFIG_CHKSUM) || defined(BOOT_RTC_ENABLED)
|
||||||
|
// calculate checksum for block of data
|
||||||
|
// from start up to (but excluding) end
|
||||||
|
static uint8 calc_chksum(uint8 *start, uint8 *end) {
|
||||||
|
uint8 chksum = CHKSUM_INIT;
|
||||||
|
while(start < end) {
|
||||||
|
chksum ^= *start;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
return chksum;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// get the rboot config
|
||||||
|
rboot_config ICACHE_FLASH_ATTR rboot_get_config(void) {
|
||||||
|
rboot_config conf;
|
||||||
|
spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)&conf, sizeof(rboot_config));
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the rboot config
|
||||||
|
// preserves the contents of the rest of the sector,
|
||||||
|
// so the rest of the sector can be used to store user data
|
||||||
|
// updates checksum automatically (if enabled)
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf) {
|
||||||
|
uint8 *buffer;
|
||||||
|
buffer = (uint8*)os_malloc(SECTOR_SIZE);
|
||||||
|
if (!buffer) {
|
||||||
|
//os_printf("No ram!\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
conf->chksum = calc_chksum((uint8*)conf, (uint8*)&conf->chksum);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
|
||||||
|
memcpy(buffer, conf, sizeof(rboot_config));
|
||||||
|
vPortEnterCritical();
|
||||||
|
spi_flash_erase_sector(BOOT_CONFIG_SECTOR);
|
||||||
|
vPortExitCritical();
|
||||||
|
taskYIELD();
|
||||||
|
vPortEnterCritical();
|
||||||
|
//spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
|
||||||
|
spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE);
|
||||||
|
vPortExitCritical();
|
||||||
|
os_free(buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current boot rom
|
||||||
|
uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void) {
|
||||||
|
rboot_config conf;
|
||||||
|
conf = rboot_get_config();
|
||||||
|
return conf.current_rom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set current boot rom
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom) {
|
||||||
|
rboot_config conf;
|
||||||
|
conf = rboot_get_config();
|
||||||
|
if (rom >= conf.count) return false;
|
||||||
|
conf.current_rom = rom;
|
||||||
|
return rboot_set_config(&conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the write status struct, based on supplied start address
|
||||||
|
rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr) {
|
||||||
|
rboot_write_status status = {0};
|
||||||
|
status.start_addr = start_addr;
|
||||||
|
status.start_sector = start_addr / SECTOR_SIZE;
|
||||||
|
status.last_sector_erased = status.start_sector - 1;
|
||||||
|
//status.max_sector_count = 200;
|
||||||
|
//os_printf("init addr: 0x%08x\r\n", start_addr);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to do the actual writing to flash
|
||||||
|
// call repeatedly with more data (max len per write is the flash sector size (4k))
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len) {
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
uint8 *buffer;
|
||||||
|
int32 lastsect;
|
||||||
|
|
||||||
|
if (data == NULL || len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a buffer
|
||||||
|
buffer = (uint8 *)os_malloc(len + status->extra_count);
|
||||||
|
if (!buffer) {
|
||||||
|
//os_printf("No ram!\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy in any remaining bytes from last chunk
|
||||||
|
memcpy(buffer, status->extra_bytes, status->extra_count);
|
||||||
|
// copy in new data
|
||||||
|
memcpy(buffer + status->extra_count, data, len);
|
||||||
|
|
||||||
|
// calculate length, must be multiple of 4
|
||||||
|
// save any remaining bytes for next go
|
||||||
|
len += status->extra_count;
|
||||||
|
status->extra_count = len % 4;
|
||||||
|
len -= status->extra_count;
|
||||||
|
memcpy(status->extra_bytes, buffer + len, status->extra_count);
|
||||||
|
|
||||||
|
// check data will fit
|
||||||
|
//if (status->start_addr + len < (status->start_sector + status->max_sector_count) * SECTOR_SIZE) {
|
||||||
|
|
||||||
|
// erase any additional sectors needed by this chunk
|
||||||
|
lastsect = ((status->start_addr + len) - 1) / SECTOR_SIZE;
|
||||||
|
while (lastsect > status->last_sector_erased) {
|
||||||
|
status->last_sector_erased++;
|
||||||
|
spi_flash_erase_sector(status->last_sector_erased);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write current chunk
|
||||||
|
//os_printf("write addr: 0x%08x, len: 0x%04x\r\n", status->start_addr, len);
|
||||||
|
if (spi_flash_write(status->start_addr, (uint32 *)((void*)buffer), len) == SPI_FLASH_RESULT_OK) {
|
||||||
|
ret = true;
|
||||||
|
status->start_addr += len;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
os_free(buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_RTC_ENABLED
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_rtc_data(rboot_rtc_data *rtc) {
|
||||||
|
if (system_rtc_mem_read(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data))) {
|
||||||
|
return (rtc->chksum == calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_rtc_data(rboot_rtc_data *rtc) {
|
||||||
|
// calculate checksum
|
||||||
|
rtc->chksum = calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum);
|
||||||
|
return system_rtc_mem_write(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_temp_rom(uint8 rom) {
|
||||||
|
rboot_rtc_data rtc;
|
||||||
|
// invalid data in rtc?
|
||||||
|
if (!rboot_get_rtc_data(&rtc)) {
|
||||||
|
// set basics
|
||||||
|
rtc.magic = RBOOT_RTC_MAGIC;
|
||||||
|
rtc.last_mode = MODE_STANDARD;
|
||||||
|
rtc.last_rom = 0;
|
||||||
|
}
|
||||||
|
// set next boot to temp mode with specified rom
|
||||||
|
rtc.next_mode = MODE_TEMP_ROM;
|
||||||
|
rtc.temp_rom = rom;
|
||||||
|
|
||||||
|
return rboot_set_rtc_data(&rtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_last_boot_rom(uint8 *rom) {
|
||||||
|
rboot_rtc_data rtc;
|
||||||
|
if (rboot_get_rtc_data(&rtc)) {
|
||||||
|
*rom = rtc.last_rom;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_last_boot_mode(uint8 *mode) {
|
||||||
|
rboot_rtc_data rtc;
|
||||||
|
if (rboot_get_rtc_data(&rtc)) {
|
||||||
|
*mode = rtc.last_mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
136
extras/rboot-ota/rboot-api.h
Normal file
136
extras/rboot-ota/rboot-api.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#ifndef __RBOOT_API_H__
|
||||||
|
#define __RBOOT_API_H__
|
||||||
|
|
||||||
|
/** @defgroup rboot rBoot API
|
||||||
|
* @brief rBoot for ESP8266 API allows runtime code to access the rBoot configuration.
|
||||||
|
* Configuration may be read to use within the main firmware or updated to
|
||||||
|
* affect next boot behavior.
|
||||||
|
* @copyright 2015 Richard A Burton
|
||||||
|
* @author richardaburton@gmail.com
|
||||||
|
* @author OTA code based on SDK sample from Espressif
|
||||||
|
* @license See licence.txt for license terms.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rboot.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @brief Structure defining flash write status
|
||||||
|
* @note The user application should not modify the contents of this
|
||||||
|
* structure.
|
||||||
|
* @see rboot_write_flash
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32 start_addr;
|
||||||
|
uint32 start_sector;
|
||||||
|
//uint32 max_sector_count;
|
||||||
|
int32 last_sector_erased;
|
||||||
|
uint8 extra_count;
|
||||||
|
uint8 extra_bytes[4];
|
||||||
|
} rboot_write_status;
|
||||||
|
|
||||||
|
/** @brief Read rBoot configuration from flash
|
||||||
|
* @retval rboot_config Copy of the rBoot configuration
|
||||||
|
* @note Returns rboot_config (defined in rboot.h) allowing you to modify any values
|
||||||
|
* in it, including the ROM layout.
|
||||||
|
*/
|
||||||
|
rboot_config ICACHE_FLASH_ATTR rboot_get_config(void);
|
||||||
|
|
||||||
|
/** @brief Write rBoot configuration to flash memory
|
||||||
|
* @param conf pointer to a rboot_config structure containing configuration to save
|
||||||
|
* @retval bool True on success
|
||||||
|
* @note Saves the rboot_config structure back to configuration sector (BOOT_CONFIG_SECTOR)
|
||||||
|
* of the flash, while maintaining the contents of the rest of the sector.
|
||||||
|
* You can use the rest of this sector for your app settings, as long as you
|
||||||
|
* protect this structure when you do so.
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf);
|
||||||
|
|
||||||
|
/** @brief Get index of current ROM
|
||||||
|
* @retval uint8 Index of the current ROM
|
||||||
|
* @note Get the currently selected boot ROM (this will be the currently
|
||||||
|
* running ROM, as long as you haven't changed it since boot or rBoot
|
||||||
|
* booted the rom in temporary boot mode, see rboot_get_last_boot_rom).
|
||||||
|
*/
|
||||||
|
uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void);
|
||||||
|
|
||||||
|
/** @brief Set the index of current ROM
|
||||||
|
* @param rom The index of the ROM to use on next boot
|
||||||
|
* @retval bool True on success
|
||||||
|
* @note Set the current boot ROM, which will be used when next restarted.
|
||||||
|
* @note This function re-writes the whole configuration to flash memory (not just the current ROM index)
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom);
|
||||||
|
|
||||||
|
/** @brief Initialise flash write process
|
||||||
|
* @param start_addr Address on the SPI flash to begin write to
|
||||||
|
* @note Call once before starting to pass data to write to flash memory with rboot_write_flash function.
|
||||||
|
* start_addr is the address on the SPI flash to write from. Returns a status structure which
|
||||||
|
* must be passed back on each write. The contents of the structure should not
|
||||||
|
* be modified by the calling code.
|
||||||
|
*/
|
||||||
|
rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr);
|
||||||
|
|
||||||
|
/** @brief Write data to flash memory
|
||||||
|
* @param status Pointer to rboot_write_status structure defining the write status
|
||||||
|
* @param data Pointer to a block of uint8 data elements to be written to flash
|
||||||
|
* @param len Quantity of uint8 data elements to write to flash
|
||||||
|
* @note Call repeatedly to write data to the flash, starting at the address
|
||||||
|
* specified on the prior call to rboot_write_init. Current write position is
|
||||||
|
* tracked automatically. This method is likely to be called each time a packet
|
||||||
|
* of OTA data is received over the network.
|
||||||
|
* @note Call rboot_write_init before calling this function to get the rboot_write_status structure
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len);
|
||||||
|
|
||||||
|
#ifdef BOOT_RTC_ENABLED
|
||||||
|
/** @brief Get rBoot status/control data from RTC data area
|
||||||
|
* @param rtc Pointer to a rboot_rtc_data structure to be populated
|
||||||
|
* @retval bool True on success, false if no data/invalid checksum (in which
|
||||||
|
* case do not use the contents of the structure)
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_rtc_data(rboot_rtc_data *rtc);
|
||||||
|
|
||||||
|
/** @brief Set rBoot status/control data in RTC data area
|
||||||
|
* @param rtc pointer to a rboot_rtc_data structure
|
||||||
|
* @retval bool True on success
|
||||||
|
* @note The checksum will be calculated automatically for you.
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_rtc_data(rboot_rtc_data *rtc);
|
||||||
|
|
||||||
|
/** @brief Set temporary rom for next boot
|
||||||
|
* @param rom Rom slot number for next boot
|
||||||
|
* @retval bool True on success
|
||||||
|
* @note This call will tell rBoot to temporarily boot the specified rom on
|
||||||
|
* the next boot. This is does not update the stored rBoot config on
|
||||||
|
* the flash, so after another reset it will boot back to the original
|
||||||
|
* rom.
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_temp_rom(uint8 rom);
|
||||||
|
|
||||||
|
/** @brief Get the last booted rom slot number
|
||||||
|
* @param rom Pointer to rom slot number variable to populate
|
||||||
|
* @retval bool True on success, false if no data/invalid checksum
|
||||||
|
* @note This will find the currently running rom, even if booted as a
|
||||||
|
* temporary rom.
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_last_boot_rom(uint8 *rom);
|
||||||
|
|
||||||
|
/** @brief Get the last boot mode
|
||||||
|
* @param mode Pointer to mode variable to populate
|
||||||
|
* @retval bool True on success, false if no data/invalid checksum
|
||||||
|
* @note This will indicate the type of boot: MODE_STANDARD, MODE_GPIO_ROM or
|
||||||
|
* MODE_TEMP_ROM.
|
||||||
|
*/
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_get_last_boot_mode(uint8 *mode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
#endif
|
|
@ -10,17 +10,10 @@
|
||||||
#include <FreeRTOS.h>
|
#include <FreeRTOS.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
|
||||||
#include "rboot-ota.h"
|
#include <rboot.h>
|
||||||
|
|
||||||
#define ROM_MAGIC_OLD 0xe9
|
#define ROM_MAGIC_OLD 0xe9
|
||||||
#define ROM_MAGIC_NEW 0xea
|
#define ROM_MAGIC_NEW 0xea
|
||||||
#define CHECKSUM_INIT 0xef
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define RBOOT_DEBUG(f_, ...) printf((f_), __VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define RBOOT_DEBUG(f_, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint8_t magic;
|
uint8_t magic;
|
||||||
|
@ -35,67 +28,6 @@ typedef struct __attribute__((packed)) {
|
||||||
} section_header_t;
|
} section_header_t;
|
||||||
|
|
||||||
|
|
||||||
// get the rboot config
|
|
||||||
rboot_config_t rboot_get_config() {
|
|
||||||
rboot_config_t conf;
|
|
||||||
sdk_spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)&conf, sizeof(rboot_config_t));
|
|
||||||
return conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the rboot config
|
|
||||||
// preserves contents of rest of sector, so rest
|
|
||||||
// of sector can be used to store user data
|
|
||||||
// updates checksum automatically, if enabled
|
|
||||||
bool rboot_set_config(rboot_config_t *conf) {
|
|
||||||
uint8_t *buffer;
|
|
||||||
#ifdef RBOOT_CONFIG_CHKSUM
|
|
||||||
uint8_t chksum;
|
|
||||||
uint8_t *ptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buffer = (uint8_t*)malloc(SECTOR_SIZE);
|
|
||||||
if (!buffer) {
|
|
||||||
printf("rboot_set_config: Failed to allocate sector buffer\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BOOT_CONFIG_CHKSUM
|
|
||||||
chksum = CHKSUM_INIT;
|
|
||||||
for (ptr = (uint8_t*)conf; ptr < &conf->chksum; ptr++) {
|
|
||||||
chksum ^= *ptr;
|
|
||||||
}
|
|
||||||
conf->chksum = chksum;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sdk_spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)buffer, SECTOR_SIZE);
|
|
||||||
memcpy(buffer, conf, sizeof(rboot_config_t));
|
|
||||||
vPortEnterCritical();
|
|
||||||
sdk_spi_flash_erase_sector(BOOT_CONFIG_SECTOR);
|
|
||||||
vPortExitCritical();
|
|
||||||
taskYIELD();
|
|
||||||
vPortEnterCritical();
|
|
||||||
sdk_spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32_t*)buffer, SECTOR_SIZE);
|
|
||||||
vPortExitCritical();
|
|
||||||
free(buffer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get current boot rom
|
|
||||||
uint8_t rboot_get_current_rom() {
|
|
||||||
rboot_config_t conf;
|
|
||||||
conf = rboot_get_config();
|
|
||||||
return conf.current_rom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set current boot rom
|
|
||||||
bool rboot_set_current_rom(uint8_t rom) {
|
|
||||||
rboot_config_t conf;
|
|
||||||
conf = rboot_get_config();
|
|
||||||
if (rom >= conf.count) return false;
|
|
||||||
conf.current_rom = rom;
|
|
||||||
return rboot_set_config(&conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that a valid-looking rboot image is found at this offset on the flash, and
|
// Check that a valid-looking rboot image is found at this offset on the flash, and
|
||||||
// takes up 'expected_length' bytes.
|
// takes up 'expected_length' bytes.
|
||||||
bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message)
|
bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message)
|
||||||
|
@ -120,7 +52,7 @@ bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **
|
||||||
|
|
||||||
int remaining_sections = image_header.section_count;
|
int remaining_sections = image_header.section_count;
|
||||||
|
|
||||||
uint8_t checksum = CHECKSUM_INIT;
|
uint8_t checksum = CHKSUM_INIT;
|
||||||
|
|
||||||
while(remaining_sections > 0 && offset < end_offset)
|
while(remaining_sections > 0 && offset < end_offset)
|
||||||
{
|
{
|
34
extras/rboot-ota/rboot-integration.h
Normal file
34
extras/rboot-ota/rboot-integration.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// The rboot project provides this file for making rboot fit other projects
|
||||||
|
|
||||||
|
#ifndef __RBOOT_INTEGRATION_H__
|
||||||
|
#define __RBOOT_INTEGRATION_H__
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <espressif/spi_flash.h>
|
||||||
|
#include <espressif/esp_system.h>
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
|
#define uint8 uint8_t
|
||||||
|
#define uint16 uint16_t
|
||||||
|
#define uint32 uint32_t
|
||||||
|
#define int32 int32_t
|
||||||
|
#define ICACHE_FLASH_ATTR
|
||||||
|
#define spi_flash_read sdk_spi_flash_read
|
||||||
|
#define spi_flash_erase_sector sdk_spi_flash_erase_sector
|
||||||
|
#define spi_flash_write sdk_spi_flash_write
|
||||||
|
#define os_malloc malloc
|
||||||
|
#define os_free free
|
||||||
|
#define system_rtc_mem_read sdk_system_rtc_mem_read
|
||||||
|
#define system_rtc_mem_write sdk_system_rtc_mem_write
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define RBOOT_DEBUG(f_, ...) printf((f_), __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define RBOOT_DEBUG(f_, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Check that a valid-looking rboot image is found at this offset on the flash, and
|
||||||
|
// takes up 'expected_length' bytes.
|
||||||
|
bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message);
|
||||||
|
#endif // __RBOOT_INTEGRATION_H__
|
|
@ -1,55 +0,0 @@
|
||||||
#ifndef __RBOOT_OTA_H__
|
|
||||||
#define __RBOOT_OTA_H__
|
|
||||||
/* rboot-ota client API
|
|
||||||
*
|
|
||||||
* Ported from https://github.com/raburton/esp8266/ to esp-open-rtos
|
|
||||||
*
|
|
||||||
* BSD Licensed as per the file LICENSE in the top-level directory.
|
|
||||||
* Copyright (c) 2015 Richard A Burton & SuperHouse Pty Ltd
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <rboot-config.h>
|
|
||||||
|
|
||||||
/* rboot config block structure (stored in flash offset 0x1000)
|
|
||||||
*
|
|
||||||
* Structure taken from rboot.h revision a4724ede22
|
|
||||||
* The version of rboot you're using has to match this structure
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint8_t magic; // our magic
|
|
||||||
uint8_t version; // config struct version
|
|
||||||
uint8_t mode; // boot loader mode
|
|
||||||
uint8_t current_rom; // currently selected rom
|
|
||||||
uint8_t gpio_rom; // rom to use for gpio boot
|
|
||||||
uint8_t count; // number of roms in use
|
|
||||||
uint8_t unused[2]; // padding
|
|
||||||
uint32_t roms[RBOOT_MAX_ROMS]; // flash addresses of the roms
|
|
||||||
#ifdef RBOOT_CONFIG_CHKSUM
|
|
||||||
uint8_t chksum; // config chksum
|
|
||||||
#endif
|
|
||||||
} rboot_config_t;
|
|
||||||
|
|
||||||
|
|
||||||
#define SECTOR_SIZE 0x1000
|
|
||||||
#define BOOT_CONFIG_SECTOR 1
|
|
||||||
|
|
||||||
// timeout for the initial connect (in ms)
|
|
||||||
#define OTA_CONNECT_TIMEOUT 10000
|
|
||||||
|
|
||||||
// timeout for the download and flash to complete (in ms), once connected
|
|
||||||
#define OTA_DOWNLOAD_TIMEOUT 20000
|
|
||||||
|
|
||||||
#define UPGRADE_FLAG_IDLE 0x00
|
|
||||||
#define UPGRADE_FLAG_START 0x01
|
|
||||||
#define UPGRADE_FLAG_FINISH 0x02
|
|
||||||
|
|
||||||
#define FLASH_BY_ADDR 0xff
|
|
||||||
|
|
||||||
rboot_config_t rboot_get_config();
|
|
||||||
bool rboot_set_config(rboot_config_t *conf);
|
|
||||||
uint8_t rboot_get_current_rom();
|
|
||||||
bool rboot_set_current_rom(uint8_t rom);
|
|
||||||
bool rboot_verify_image(uint32_t offset, uint32_t expected_length, const char **error_message);
|
|
||||||
|
|
||||||
#endif
|
|
111
extras/rboot-ota/rboot.h
Normal file
111
extras/rboot-ota/rboot.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#ifndef __RBOOT_H__
|
||||||
|
#define __RBOOT_H__
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RBOOT_INTEGRATION
|
||||||
|
|
||||||
|
// uncomment to use only c code
|
||||||
|
// if you aren't using gcc you may need to do this
|
||||||
|
//#define BOOT_NO_ASM
|
||||||
|
|
||||||
|
// uncomment to have a checksum on the boot config
|
||||||
|
//#define BOOT_CONFIG_CHKSUM
|
||||||
|
|
||||||
|
// uncomment to enable big flash support (>1MB)
|
||||||
|
#define BOOT_BIG_FLASH
|
||||||
|
|
||||||
|
// uncomment to enable 2 way communication between
|
||||||
|
// rBoot and the user app via the esp rtc data area
|
||||||
|
#define BOOT_RTC_ENABLED
|
||||||
|
|
||||||
|
// uncomment to enable GPIO booting
|
||||||
|
//#define BOOT_GPIO_ENABLED
|
||||||
|
|
||||||
|
// uncomment to include .irom0.text section in the checksum
|
||||||
|
// roms must be built with esptool2 using -iromchksum option
|
||||||
|
//#define BOOT_IROM_CHKSUM
|
||||||
|
|
||||||
|
// uncomment to add a boot delay, allows you time to connect
|
||||||
|
// a terminal before rBoot starts to run and output messages
|
||||||
|
// value is in microseconds
|
||||||
|
//#define BOOT_DELAY_MICROS 2000000
|
||||||
|
|
||||||
|
// increase if required
|
||||||
|
#define MAX_ROMS 4
|
||||||
|
|
||||||
|
#define CHKSUM_INIT 0xef
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 0x1000
|
||||||
|
#define BOOT_CONFIG_SECTOR 1
|
||||||
|
|
||||||
|
#define BOOT_CONFIG_MAGIC 0xe1
|
||||||
|
#define BOOT_CONFIG_VERSION 0x01
|
||||||
|
|
||||||
|
#define MODE_STANDARD 0x00
|
||||||
|
#define MODE_GPIO_ROM 0x01
|
||||||
|
#define MODE_TEMP_ROM 0x02
|
||||||
|
|
||||||
|
#define RBOOT_RTC_MAGIC 0x2334ae68
|
||||||
|
#define RBOOT_RTC_READ 1
|
||||||
|
#define RBOOT_RTC_WRITE 0
|
||||||
|
#define RBOOT_RTC_ADDR 64
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @brief Structure containing rBoot configuration
|
||||||
|
* @note ROM addresses must be multiples of 0x1000 (flash sector aligned).
|
||||||
|
* Without BOOT_BIG_FLASH only the first 8Mbit (1MB) of the chip will
|
||||||
|
* be memory mapped so ROM slots containing .irom0.text sections must
|
||||||
|
* remain below 0x100000. Slots beyond this will only be accessible via
|
||||||
|
* spi read calls, so use these for stored resources, not code. With
|
||||||
|
* BOOT_BIG_FLASH the flash will be mapped in chunks of 8MBit (1MB), so
|
||||||
|
* ROMs can be anywhere, but must not straddle two 8MBit (1MB) blocks.
|
||||||
|
* @ingroup rboot
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8 magic; ///< Our magic, identifies rBoot configuration - should be BOOT_CONFIG_MAGIC
|
||||||
|
uint8 version; ///< Version of configuration structure - should be BOOT_CONFIG_VERSION
|
||||||
|
uint8 mode; ///< Boot loader mode (MODE_STANDARD | MODE_GPIO_ROM)
|
||||||
|
uint8 current_rom; ///< Currently selected ROM (will be used for next standard boot)
|
||||||
|
uint8 gpio_rom; ///< ROM to use for GPIO boot (hardware switch) with mode set to MODE_GPIO_ROM
|
||||||
|
uint8 count; ///< Quantity of ROMs available to boot
|
||||||
|
uint8 unused[2]; ///< Padding (not used)
|
||||||
|
uint32 roms[MAX_ROMS]; ///< Flash addresses of each ROM
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
uint8 chksum; ///< Checksum of this configuration structure (if BOOT_CONFIG_CHKSUM defined)
|
||||||
|
#endif
|
||||||
|
} rboot_config;
|
||||||
|
|
||||||
|
#ifdef BOOT_RTC_ENABLED
|
||||||
|
/** @brief Structure containing rBoot status/control data
|
||||||
|
* @note This structure is used to, optionally, communicate between rBoot and
|
||||||
|
* the user app. It is stored in the ESP RTC data area.
|
||||||
|
* @ingroup rboot
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32 magic; ///< Magic, identifies rBoot RTC data - should be RBOOT_RTC_MAGIC
|
||||||
|
uint8 next_mode; ///< The next boot mode, defaults to MODE_STANDARD - can be set to MODE_TEMP_ROM
|
||||||
|
uint8 last_mode; ///< The last (this) boot mode - can be MODE_STANDARD, MODE_GPIO_ROM or MODE_TEMP_ROM
|
||||||
|
uint8 last_rom; ///< The last (this) boot rom number
|
||||||
|
uint8 temp_rom; ///< The next boot rom number when next_mode set to MODE_TEMP_ROM
|
||||||
|
uint8 chksum; ///< Checksum of this structure this will be updated for you passed to the API
|
||||||
|
} rboot_rtc_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
*NOTE: This rboot-ota and the TFTP server ota-tftp.h are specific to esp-open-rtos. The below Makefile is from the upstream rboot-ota project.*
|
*NOTE: This rboot-ota and the TFTP server ota-tftp.h are specific to esp-open-rtos. The below Makefile is from the upstream rboot-ota project and the rboot code is taken from #75ca33b.*
|
||||||
|
|
||||||
For more details on OTA in esp-open-rtos, see https://github.com/SuperHouse/esp-open-rtos/wiki/OTA-Update-Configuration
|
For more details on OTA in esp-open-rtos, see https://github.com/SuperHouse/esp-open-rtos/wiki/OTA-Update-Configuration
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue