Auf meinem ESP32 habe ich 2 Partitionen mit gültigen Firmwares darauf: app0 und app1. Meine ursprüngliche Firmware war auf app0, ich habe die neue Firmware auf app1 hochgeladen und dann das OTA-Update durchgeführt. Ich habe darauf geachtet, die neue Bootpartition mit esp_ota_set_boot_patition auf app1 zu setzen. In der Konsole sah ich, dass die Firmware geflasht wurde und dass es erfolgreich war, da der Code der neuen Firmware ausgeführt wurde. Dann schloss ich die Konsole und lud einen neuen Code in sie hoch. Als ich das tat, sah ich, dass die Boot-Partition immer noch app0 war. Warum ist das so? Ich dachte, nach esp_ota_set_boot_partition speichert die ota-Datenpartition die neue Booteinstellung und bootet danach nur noch in app1?
:
Verschoben durch Moderator
Vielleicht enthält der Upload rine fehlerhafte Prüfsumme. Was meldet denn der Bootloader beim Neustart?
Update to app1 complete! Switching to app1... Switched to app1. Rebooting... ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0xc (RTC_SW_CPU_RST),boot:0x29 (SPI_FAST_FLASH_BOOT) Saved PC:0x42029956 SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3808,len:0x4bc load:0x403c9700,len:0xbd8 load:0x403cc700,len:0x2a0c entry 0x403c98d0 Listing directory: / FILE: firmware.bin SIZE: 310368 Boot partition: app1 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 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF Ready! Die Hex-Werte zeigen die OTA data partition an. In der neuen Firmware gibt es einen Code, der esp_ota_mark_app_valid_cancel_rollback() aufruft und dann die aktuelle Bootpartition anzeigt (hier Boot partition: app1). Aber wenn ich dann die Konsole schließe und in Platformio auf Upload und Monitor klicke (mit neuem Code, der nur die Boot-Partition anzeigt), steht dort „Boot partition: app0“. Das OTA-Update wird mit der Funktion PerformOTAUpdate durchgeführt. Sie verwendet eine Datei aus dem SPIFFS-Speicher und schreibt sie auf die app1-Partition. Die Funktion ruft
1 | esp_ota_begin
|
2 | esp_ota_write
|
3 | esp_ota_end
|
4 | esp_ota_set_boot_partition
|
5 | ESP.restart |
Hier der Code dieser Funktion:
1 | void PerformOTAUpdate(File &firmware) { |
2 | const esp_partition_t *app1_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL); |
3 | if (!app1_partition) { |
4 | USBSerial.println("Error: app1 partition not found!"); |
5 | return; |
6 | }
|
7 | |
8 | esp_ota_handle_t ota_handle; |
9 | if (esp_ota_begin(app1_partition, OTA_SIZE_UNKNOWN, &ota_handle) != ESP_OK) { |
10 | USBSerial.println("Failed to start OTA update!"); |
11 | return; |
12 | }
|
13 | |
14 | USBSerial.printf("Starting OTA update to %s...\n", app1_partition->label); |
15 | size_t written = 0; |
16 | uint8_t buf[1024]; |
17 | |
18 | // write from SPIFFS to OTA app1 partition
|
19 | while (firmware.available()) { |
20 | size_t readBytes = firmware.read(buf, sizeof(buf)); |
21 | if (readBytes > 0) { |
22 | if (esp_ota_write(ota_handle, buf, readBytes) != ESP_OK) { |
23 | USBSerial.println("Error writing OTA data!"); |
24 | esp_ota_end(ota_handle); |
25 | return; |
26 | }
|
27 | written += readBytes; |
28 | USBSerial.printf("Written %d bytes...\n", written); |
29 | }
|
30 | }
|
31 | |
32 | if (esp_ota_end(ota_handle) != ESP_OK) { |
33 | USBSerial.println("Error finalizing OTA update!"); |
34 | return; |
35 | }
|
36 | |
37 | // sets poot partition and restarts
|
38 | USBSerial.println("Update to app1 complete! Switching to app1..."); |
39 | if (esp_ota_set_boot_partition(app1_partition) == ESP_OK) { |
40 | USBSerial.println("Switched to app1. Rebooting..."); |
41 | delay(1000); |
42 | ESP.restart(); |
43 | } else { |
44 | USBSerial.println("Failed to set app1 as boot partition!"); |
45 | }
|
46 | }
|
Der Code der neuen firmware ist eigentlich nur sowas wie
1 | void setup() |
2 | |
3 | {
|
4 | |
5 | ... // initialize Serial |
6 | |
7 | esp_ota_mark_app_valid_cancel_rollback(); |
8 | |
9 | check_boot_partition(); // displays current boot partition |
10 | |
11 | }
|
Hab die Lösung gefunden: Ich hatte immer gedacht, dass bei einem Upload nur der Code upgeloadet wird. Jedoch wird alles neu formatiert, die Firmware neu raufgespielt, etc. Dabei wird auch die OTA data partition gelöscht / neu initialisiert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.