OTA
OTA Constants
#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
OTA platform selection constants. Set MG_OTA to one of these values to select the target platform for firmware updates.
MG_IRAM
#define MG_IRAM __attribute__((noinline, section(".iram")))
Macro to place functions in RAM for execution during flash operations. Used when MG_OTA is defined (not MG_OTA_NONE). Functions marked with MG_IRAM reside in a special section that can be executed while the flash is being written.
mg_ota_begin()
bool mg_ota_begin(size_t new_firmware_size);
Start a firmware update session.
Parameters:
new_firmware_size- Expected size of the new firmware image
Return value: true on success, false on failure
Usage example:
if (mg_ota_begin(firmware_size)) {
// Ready to write firmware
} else {
// OTA begin failed
}
mg_ota_write()
bool mg_ota_write(const void *buf, size_t len);
Write a chunk of firmware data. Data must be aligned to 1k boundaries as required by the underlying flash hardware.
Parameters:
buf- Pointer to data buffer containing firmware chunklen- Length of data to write (must be aligned to 1k)
Return value: true on success, false on failure
Usage example:
if (!mg_ota_write(data, data_len)) {
// Write failed
}
mg_ota_end()
bool mg_ota_end(void);
Finalize the firmware update session. This function verifies the written firmware and prepares it for boot.
Return value: true on success, false on failure
Usage example:
if (mg_ota_end()) {
// Firmware update complete, reboot to apply
} else {
// OTA end failed
}
MG_OTA_ROLLBACK()
#define MG_OTA_ROLLBACK() do { mg_flash->swap_fn(); NVIC_SystemReset(); } while (0)
Roll back to the previously running firmware image and reset the device.
For flash-based OTA targets, the default implementation calls the platform flash swap_fn() and then resets the MCU. On single-bank targets, swap_fn() may be a no-op. Platforms that do not use mg_flash, or applications that need a custom rollback/reset sequence, can override MG_OTA_ROLLBACK() in mongoose_config.h.
MG_OTA_BOOT_CHECK(ms) calls MG_OTA_ROLLBACK() automatically when the persistent OTA state is MG_OTA_FAILED. The application can also call it explicitly from a management endpoint, typically after setting the OTA state back to MG_OTA_CONFIRMED so the next boot does not re-enter the failed-state path.
Parameters: None
Return value: None. The default implementation resets the device and does not return.
Usage example:
static void do_rollback(void *arg) {
(void) arg;
MG_OTA_ROLLBACK();
}
static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_match(hm->uri, mg_str("/api/ota/rollback"), NULL)) {
MG_OTA_STATE_SET(MG_OTA_CONFIRMED);
mg_http_reply(c, 200, "", "ok\n");
mg_timer_add(c->mgr, 500, MG_TIMER_ONCE, do_rollback, NULL);
}
}
}
See the Firmware OTA updates guide for the rollback state machine, watchdog timer, and commit flow.
MG_OTA_STATE_SET()
#define MG_OTA_STATE_SET(val) (void) (val)
Store the persistent OTA rollback state.
Define this macro in mongoose_config.h to write the OTA state to storage that
survives reset or reboot. RTC backup registers, battery-backed SRAM, FRAM, or
flash are all valid choices.
Parameters:
val- OTA state value to store:MG_OTA_CONFIRMED,MG_OTA_TESTING, orMG_OTA_FAILED
Return value: None
Default behavior: the value is discarded.
Usage example:
#define MG_OTA_STATE_SET(v) \
(*(volatile uint32_t *) 0x44007D00U = (uint32_t) (v))
MG_OTA_STATE_GET()
#define MG_OTA_STATE_GET() 0
Read the persistent OTA rollback state.
Define this macro in mongoose_config.h to read the same reset-persistent
storage written by MG_OTA_STATE_SET(). MG_OTA_BOOT_CHECK(ms) uses this value
at boot to decide whether to run normally, start the rollback timer, or roll
back immediately.
Parameters: None
Return value: one of MG_OTA_CONFIRMED, MG_OTA_TESTING, or MG_OTA_FAILED
Default behavior: returns MG_OTA_CONFIRMED.
Usage example:
#define MG_OTA_STATE_GET() (*(volatile uint32_t *) 0x44007D00U)
mg_ota_url_check()
void mg_ota_url_check(struct mg_mgr *mgr,
const char *current_version,
const char *metadata_url,
void (*fn)(const char *status));
Check for firmware updates by fetching metadata from a URL and comparing versions.
Metadata file format:
{
"version": "1.2.3",
"url": "http://my-product.com/firmwares/firmware-1.2.3.bin",
"size": 324645
}
Parameters:
mgr- Event manager to use for HTTP requestcurrent_version- Current firmware version stringmetadata_url- URL to fetch update metadata (JSON containing version info)fn- Callback function that receives status updates during the check
Return value: None
The callback function receives status strings indicating the progress or result of the update check.