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 chunk
  • len - 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, or MG_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 request
  • current_version - Current firmware version string
  • metadata_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.