ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Julian-Christoph
Posts: 4
Joined: Sat Jan 18, 2025 9:13 pm

ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby Julian-Christoph » Sat Jan 18, 2025 9:39 pm

I'm working on an ESP32-S3-WROOM-2-N32R8 (32MB Flash, 8MB PSRAM) project using PlatformIO in VSCode with the Arduino framework. My goal is to implement OTA updates, but I'm running into an issue: The ESP32 always boots from ota_0 (partition app0), even though the OTA update to ota_1 (partition app1) completes successfully without any errors.

Problem Details:
OTA update writes the new firmware to ota_1 and marks it as the boot partition successfully.
Calls to esp_ota_get_boot_partition() confirm that the boot partition has been updated to ota_1 post-update.
On reboot, the ESP32 always boots from ota_0 (instead of ota_1 as intended)

Environment:
Board: ESP32-S3-WROOM-2-N32R8V (32MB Flash, 8MB PSRAM Octal)
Platform: PlatformIO (VSCode)
Framework: Arduino
Partition Table:

Code: Select all

# Name,   Type, SubType, Offset,    Size, Flags
nvs,      data, nvs,     0x9000,    0x5000,
otadata,  data, ota,     0xE000,    0x2000,
app0,     app,  ota_0,   0x10000,   0xBB0000,
app1,     app,  ota_1,   0xBC0000,  0xBB0000,
nvm,      data, nvs,     0x1770000, 0x890000,
Analysis conducted
The following analysis has been conducted:

1. Find the current boot partition (before update)

Code: Select all

esp_ota_get_boot_partition()
Result: Current boot partition: app0

2. Check if ota partition is bootable

Code: Select all

if (_partitionIsBootable(_partition) == true) {
            Serial.println("[Updater] Partition is bootable.");
        }
Result: Partition is bootable.

3. Checked the ota partition's address

Code: Select all

Serial.println("[Updater] New partition address: " + String(_partition->address));
Result: The partition, which the new firmware is written to, shows address 0xBC0000 (app1) correctly.

4. Verified result on setting boot partition

Code: Select all

esp_err_t result = esp_ota_set_boot_partition(_partition);
Result: ESP_OK = Boot partition set to app1 without error

5. Forced the ota partition to mark app as valid after verification.

Code: Select all

 if (esp_partition_verify(_partition)) {
            // Mark the newly flashed partition as valid, if partition is valid
            esp_err_t err = esp_ota_mark_app_valid_cancel_rollback();
            if (err != ESP_OK) {
                Serial.println("[Updater] Error: Partition not valid.");
                Serial.println("[Updater] Error marking app valid! Code: " + String(err));
            } else {
                Serial.println("[Updater] Partition is valid.");
                Serial.println("[Updater] App marked as valid. OK! Code: " + String(err));
            }
        }
Result: Partition is valid. / App marked as valid.

6. Read-out the contents of ota_data partition
The following data is stored in the otadata partition (address: 0xE000, length 0x2000)

Code: Select all

01 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 9A 98 43 47
Result: This indicates that the boot loader has correctly been set to app1 as boot partition.

Question
How come that my ESP32 is still booting from partition app0 after reboot / power cycle?
The serial output confirms:

Code: Select all

Currently running from partition: Type: 0, Subtype: 16, Address: 0x10000
Address 0x10000 is app0, not as after ota update confirmed address 0xBC0000.

Thanks a lot for your help! :-)

Julian-Christoph
Posts: 4
Joined: Sat Jan 18, 2025 9:13 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby Julian-Christoph » Sun Jan 19, 2025 9:33 pm

Update: OTA Works with Small Binary, Fails with Larger Binary

After further testing, I found that the OTA update process works perfectly when I upload a smaller firmware binary file (571 KB in size). The OTA update is applied correctly, and the device boots from the new partition ota_1 (=app1) as expected.

However, when trying to update with my actual firmware (binary size: 7.8 MB), the process still fails. The ESP32-S3 still boots from ota_0 (=app0)

The serial outputs for diagnosis show one difference when reading out the 32 bytes content of the "otadata" partition immediately after completing OTA update.
The smaller (and working) binary shows this output:

Code: Select all

02 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 02 00 00 00 74 37 F6 55
When updating the larger binary (with the actual software), the output is as before:

Code: Select all

01 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 9A 98 43 47
What could cause the larger binary to fail while smaller binaries succeed? Are there additional steps or settings I should check? Who is writing data into otadata and why isn't it overwritten as it should be?

Thanks in advance for your insights!

lbernstone
Posts: 886
Joined: Mon Jul 22, 2019 3:20 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby lbernstone » Mon Jan 20, 2025 4:21 am

I believe there is a hard limit of 4MB on the amount of const space that can be mapped in the firmware. There's a reason I only made the app size 4.8MB in the 32MB partition scheme :)

Julian-Christoph
Posts: 4
Joined: Sat Jan 18, 2025 9:13 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby Julian-Christoph » Mon Jan 20, 2025 8:57 pm

Thanks a lot, Ibernstone!

Is there any chance to get around that limit of 4MB. Seems the binary file is written to partition app1, however the contents of ota_data are not updated. When trying to manually overwrite them, they always revert to factory settings.

lbernstone
Posts: 886
Joined: Mon Jul 22, 2019 3:20 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby lbernstone » Tue Jan 21, 2025 9:31 pm

OTA rollback is using the partition that works after failing to init your new partition.
You need to analyze where your space is being consumed. There are some heaps that are quite fixed in size. Embedding data in an IDF project doesn't seem to have a size limit. ESP-IDF is of course more flexible about the configuration and allows you to change many things the pre-compiled arduino will not.

lbernstone
Posts: 886
Joined: Mon Jul 22, 2019 3:20 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby lbernstone » Tue Jan 21, 2025 9:46 pm

Does the firmware work when you directly upload it with esptool rather than ota?

Julian-Christoph
Posts: 4
Joined: Sat Jan 18, 2025 9:13 pm

Re: ESP32-S3 (N32R8) boots only from ota_0 after successful OTA update – PlatformIO/Arduino

Postby Julian-Christoph » Wed Jan 22, 2025 5:19 am

Yes, then it works well.

For testing purposes I took some images and fonts out of the firmware to reduce its size to 3.9MB, Then it works as well.

Who is online

Users browsing this forum: Google [Bot] and 43 guests