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 "ota-tftp.h"
|
||||
#include "rboot-ota.h"
|
||||
#include "rboot-integration.h"
|
||||
#include "rboot.h"
|
||||
#include "rboot-api.h"
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
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",
|
||||
conf.current_rom, conf.count);
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
#include <espressif/esp_system.h>
|
||||
|
||||
#include "ota-tftp.h"
|
||||
#include "rboot-ota.h"
|
||||
#include "rboot.h"
|
||||
#include "rboot-api.h"
|
||||
|
||||
#define TFTP_FIRMWARE_FILE "firmware.bin"
|
||||
#define TFTP_OCTET_MODE "octet" /* non-case-sensitive */
|
||||
|
@ -112,7 +113,7 @@ static void tftp_task(void *listen_port)
|
|||
netbuf_delete(netbuf);
|
||||
|
||||
/* 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();
|
||||
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 <task.h>
|
||||
|
||||
#include "rboot-ota.h"
|
||||
#include <rboot.h>
|
||||
|
||||
#define ROM_MAGIC_OLD 0xe9
|
||||
#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)) {
|
||||
uint8_t magic;
|
||||
|
@ -35,67 +28,6 @@ typedef struct __attribute__((packed)) {
|
|||
} 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
|
||||
// takes up 'expected_length' bytes.
|
||||
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;
|
||||
|
||||
uint8_t checksum = CHECKSUM_INIT;
|
||||
uint8_t checksum = CHKSUM_INIT;
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue