[ESP32-S3][ESP-IDF v5.4.1] Custom Bootloader: Always Boot from ota_1 + OTA Ping-Pong Logic
Posted: Fri May 23, 2025 2:42 pm
Hello everyone,
Hello everyone,
I'm working on a custom second-stage bootloader for an ESP32-S3 project using ESP-IDF v5.4.1, and I'm facing an issue where the device does not reliably boot from the ota_1 partition, which contains my app2 firmware.
My Goal:
I want my custom bootloader to always boot from the ota_1 partition, regardless of the presence of ota_0 or the factory app.
The image app2 is flashed into ota_1.
Additionally, I want to implement OTA "ping-pong" behavior, where:
If the currently running application is in ota_1, the next OTA update goes to ota_0.
If the current app is in ota_0, the next update goes to ota_1.
This means only ota_1 is booted, but OTA data toggles between the two slots.
Project Setup:
* ESP-IDF Version:** (Specify your ESP-IDF version v5.4.1)
* Hardware: (ESP32-S3)
* Partition Table: I'm using a custom `partitions.csv` with the following structure:
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
ota_0,app,ota_0,0x110000,1M,
ota_1,app,ota_1,0x210000,1M,
Problem Description:
(Clearly describe what is going wrong. Be specific!)
Example (If it's always booting `ota_0`):** "Despite my logic to find and load `ota_1`, the device consistently boots into `app1` (from `ota_0`) or the `factory` app."
What I've Tried:
1. Modified `find_ota1_partition()` to identify `ota_1` based on its `number` (`1`) and also by its expected offset (`0x210000`).
2. Ensured `bootloader_utility_list_partitions()` correctly populates the `bootloader_part_info` array with the `number` and `offset` for each OTA partition.
3. Attempted to load `ota_1` using `bootloader_utility_load_boot_image(&bs, partitions[ota1_index].number);` after finding its index.
If anyone has code snippets or documentation references, I’d greatly appreciate you sharing them.
Please see the attached bootloader code
Thanks in advance for your time and help!
Best regards,
shubu
Hello everyone,
I'm working on a custom second-stage bootloader for an ESP32-S3 project using ESP-IDF v5.4.1, and I'm facing an issue where the device does not reliably boot from the ota_1 partition, which contains my app2 firmware.
My Goal:
I want my custom bootloader to always boot from the ota_1 partition, regardless of the presence of ota_0 or the factory app.
The image app2 is flashed into ota_1.
Additionally, I want to implement OTA "ping-pong" behavior, where:
If the currently running application is in ota_1, the next OTA update goes to ota_0.
If the current app is in ota_0, the next update goes to ota_1.
This means only ota_1 is booted, but OTA data toggles between the two slots.
Project Setup:
* ESP-IDF Version:** (Specify your ESP-IDF version v5.4.1)
* Hardware: (ESP32-S3)
* Partition Table: I'm using a custom `partitions.csv` with the following structure:
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
ota_0,app,ota_0,0x110000,1M,
ota_1,app,ota_1,0x210000,1M,
Problem Description:
(Clearly describe what is going wrong. Be specific!)
Example (If it's always booting `ota_0`):** "Despite my logic to find and load `ota_1`, the device consistently boots into `app1` (from `ota_0`) or the `factory` app."
What I've Tried:
1. Modified `find_ota1_partition()` to identify `ota_1` based on its `number` (`1`) and also by its expected offset (`0x210000`).
2. Ensured `bootloader_utility_list_partitions()` correctly populates the `bootloader_part_info` array with the `number` and `offset` for each OTA partition.
3. Attempted to load `ota_1` using `bootloader_utility_load_boot_image(&bs, partitions[ota1_index].number);` after finding its index.
If anyone has code snippets or documentation references, I’d greatly appreciate you sharing them.
Please see the attached bootloader code
Thanks in advance for your time and help!
Best regards,
shubu