mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-31 13:00:49 +00:00
Merge pull request #3574 from cesanta/rollback
Add MG_OTA_{ROLLBACK,STATE_SET,STATE_GET}
This commit is contained in:
16 files changed
+345
-131
No files matched your search
+80
-25
@@ -3294,24 +3294,24 @@ extern void mg_mqtt_poll(struct mg_mgr *);
|
||||
|
||||
|
||||
|
||||
#define MG_OTA_NONE 0 // No OTA support
|
||||
#define MG_OTA_STM32H5 1 // STM32 H5
|
||||
#define MG_OTA_STM32H7 2 // STM32 H7
|
||||
#define MG_OTA_STM32H7_DUAL_CORE 3 // STM32 H7 dual core
|
||||
#define MG_OTA_STM32F 4 // STM32 F7/F4/F2
|
||||
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
||||
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
||||
#define MG_OTA_RT1020 300 // IMXRT1020
|
||||
#define MG_OTA_RT1050 301 // IMXRT1050
|
||||
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||
#define MG_OTA_MCXN 310 // MCXN947
|
||||
#define MG_OTA_RW612 320 // FRDM-RW612
|
||||
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
||||
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
||||
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
||||
#define MG_OTA_CUSTOM 1000 // Custom implementation
|
||||
#define MG_OTA_NONE 0 // No OTA support
|
||||
#define MG_OTA_STM32H5 1 // STM32 H5
|
||||
#define MG_OTA_STM32H7 2 // STM32 H7
|
||||
#define MG_OTA_STM32H7_DUAL_CORE 3 // STM32 H7 dual core
|
||||
#define MG_OTA_STM32F 4 // STM32 F7/F4/F2
|
||||
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
||||
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
||||
#define MG_OTA_RT1020 300 // IMXRT1020
|
||||
#define MG_OTA_RT1050 301 // IMXRT1050
|
||||
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||
#define MG_OTA_MCXN 310 // MCXN947
|
||||
#define MG_OTA_RW612 320 // FRDM-RW612
|
||||
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
||||
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
||||
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
||||
#define MG_OTA_CUSTOM 1000 // Custom implementation
|
||||
|
||||
#ifndef MG_OTA
|
||||
#define MG_OTA MG_OTA_NONE
|
||||
@@ -3321,18 +3321,73 @@ extern void mg_mqtt_poll(struct mg_mgr *);
|
||||
#define MG_IRAM __attribute__((noinline, section(".iram")))
|
||||
#else
|
||||
#define MG_IRAM
|
||||
#endif // compiler
|
||||
#endif // IRAM
|
||||
#endif // OTA
|
||||
#endif // compiler
|
||||
#endif // IRAM
|
||||
#endif // OTA
|
||||
|
||||
// Firmware update API
|
||||
bool mg_ota_begin(size_t new_firmware_size); // Start writing
|
||||
bool mg_ota_write(const void *buf, size_t len); // Write chunk, aligned to 1k
|
||||
bool mg_ota_end(void); // Stop writing
|
||||
void mg_ota_url_check(struct mg_mgr *mgr,
|
||||
const char *current_version,
|
||||
const char *metadata_url,
|
||||
void (*fn)(const char *status));
|
||||
|
||||
// MG_OTA_ROLLBACK: swap firmware banks and reset. On flash-based OTA the
|
||||
// default calls swap_fn() (no-op on single-bank) then resets. Override in
|
||||
// mongoose_config.h for platforms without mg_flash (ESP32, PicoSDK, etc.).
|
||||
#ifndef MG_OTA_ROLLBACK
|
||||
#define MG_OTA_ROLLBACK() \
|
||||
do { \
|
||||
mg_flash->swap_fn(); \
|
||||
NVIC_SystemReset(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// MG_OTA_ROLLBACK_TIMER_START(seconds): arm a hardware watchdog as the rollback
|
||||
// deadline. If it fires before MG_OTA_STATE_SET(MG_OTA_CONFIRMED), the device
|
||||
// resets and MG_OTA_STATE_GET() == MG_OTA_FAILED triggers MG_OTA_ROLLBACK().
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_START
|
||||
#define MG_OTA_ROLLBACK_TIMER_START(seconds) (void) (seconds)
|
||||
#endif
|
||||
|
||||
// OTA state values for MG_OTA_STATE_GET / MG_OTA_STATE_SET.
|
||||
// MG_OTA_CONFIRMED: firmware is committed, normal operation.
|
||||
// MG_OTA_TESTING: new firmware booted for the first time; IWDG is armed.
|
||||
// If the device reboots while in this state, it transitions
|
||||
// to MG_OTA_FAILED and rolls back on the next boot.
|
||||
// MG_OTA_FAILED: previous boot did not commit in time; rollback on next
|
||||
// boot.
|
||||
enum { MG_OTA_CONFIRMED = 0, MG_OTA_TESTING = 1, MG_OTA_FAILED = 2 };
|
||||
|
||||
// Persistent OTA state storage. Define in mongoose_config.h to use a
|
||||
// location that survives resets
|
||||
#ifndef MG_OTA_STATE_GET
|
||||
#define MG_OTA_STATE_GET() 0
|
||||
#endif
|
||||
#ifndef MG_OTA_STATE_SET
|
||||
#define MG_OTA_STATE_SET(val) (void) (val)
|
||||
#endif
|
||||
|
||||
// Call once at boot. Arms the rollback watchdog for (seconds) seconds when
|
||||
// the new firmware is in TESTING state. Rolls back immediately if FAILED.
|
||||
// boot (TESTING) → set FAILED → arm IWDG → run firmware
|
||||
// ├── commit called → set CONFIRMED → NVIC_SystemReset() → clean boot
|
||||
// └── IWDG fires → hard reset → boot → state is still FAILED → rollback
|
||||
#define MG_OTA_BOOT_CHECK(seconds) \
|
||||
do { \
|
||||
if (MG_OTA_STATE_GET() == MG_OTA_FAILED) { \
|
||||
MG_OTA_STATE_SET(MG_OTA_CONFIRMED); \
|
||||
MG_INFO(("Commit deadline expired, rolling back")); \
|
||||
MG_OTA_ROLLBACK(); \
|
||||
} else if (MG_OTA_STATE_GET() == MG_OTA_TESTING) { \
|
||||
MG_OTA_STATE_SET(MG_OTA_FAILED); \
|
||||
MG_INFO(("New firmware: commit within %u sec or rolls back", \
|
||||
(unsigned) (seconds))); \
|
||||
MG_OTA_ROLLBACK_TIMER_START(seconds); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Pull based OTA over HTTP
|
||||
void mg_ota_url_check(struct mg_mgr *mgr, const char *current_version,
|
||||
const char *metadata_url, void (*fn)(const char *status));
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user