Skip to main content

Module ota

Module ota 

Source
Expand description

Over The Air Updates (OTA)

The OTA update mechanism allows a device to update itself based on data received while the normal firmware is running (for example, over Wi-Fi or Bluetooth.)

§Requirements

OTA updates needs a different partition table than the default one. For being able to update the firmware while running, we need to have at least 2 OTA partitions. Learn more about partition tables on esp-idf documentation.

To use a different partition than the default, you should create a CSV file (or download one from the esp-idf repository). For example, you can use this partition table that defines 2 OTA partitions of 1,7Mb:

nvs,      data, nvs,     ,        0x6000,
otadata,  data, ota,     ,        0x2000,
phy_init, data, phy,     ,        0x1000,
ota_0,    app,  ota_0,   ,        1700K,
ota_1,    app,  ota_1,   ,        1700K,

Then, configure espflash to use this partition table by creating an espflash.toml:

partition_table = "./partition-table.csv"

Once an OTA update have been done, the ESP will continue to boot on the second OTA partition. You can reset the booting partition by using the --erase-parts otadata option of espflash. Add it to the runner command in your project .cargo/config.yml file.

§Rollback

Once an OTA update happened and the ESP reboots, you have the opportunity to mark the new firmware has valid, or rollback to a previously working firmware.

By default, a new firmware will continue to be selected by the bootloader until it is explicitly marked as invalid. You can change this behavior by setting the CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option. When enabled, if a reset happen before the firmware is marked as valid, the bootloader will automatically rollback to the previous valid firmware.

To enable this option, add this line to your sdkconfig.defaults file:

CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y

Then add --bootloader ./target/<your arch>/debug/bootloader.bin option to the runner command of your .cargo/config.yml file. For example:

[target.xtensa-esp32-espidf]
runner = "espflash flash --monitor --erase-parts otadata --bootloader ./target/xtensa-esp32-espidf/debug/bootloader.bin"

§Examples

The following example shows approximate steps for performing an OTA update.

// 1. Obtain an instance of OTA:
let mut ota = EspOta::new().expect("obtain OTA instance");

// 2. Initiate update and obtain an instance of `EspOtaUpdate`:
let mut update = ota.initiate_update().expect("initiate OTA");

// 3. Write the program data:
while let Some(data) = my_wireless.get_ota_data() {
    update.write(&data).expect("write OTA data");
}

// 4. Finalize update:
update.complete().expect("complete OTA");

// 5. Reboot:
esp_idf_svc::hal::reset::restart();

After rebooting and confirming that the new firmware works, mark it as valid. If this is not done, firmware will be rolled back.

// Note: starting a new scope here to ensure that ota instance is dropped at the end.
{
    let mut ota = EspOta::new().expect("obtain OTA instance");
    ota.mark_running_slot_valid().expect("mark app as valid");
}

Structs§

EspFirmwareInfoLoad
A firmware info loader that tries to read the firmware info directly from a user-supplied buffer which can be re-used for other purposes afterwards.
EspFirmwareInfoLoaderDeprecated
EspNativeFirmwareInfo
Native ESP-IDF firmware information
EspOta
EspOtaUpdate
EspOtaUpdateFinished
FirmwareInfo
Slot
UpdateProgress

Enums§

LoadResult
SlotState