Forum: Mikrocontroller und Digitale Elektronik ESP32 OTA Update hat nach Reboot / Code Upload keinen Effekt


von Hey H. (hey_h)


Lesenswert?

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
von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Vielleicht enthält der Upload rine fehlerhafte Prüfsumme. Was meldet 
denn der Bootloader beim Neustart?

von Hey H. (hey_h)


Lesenswert?

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
}

von Hey H. (hey_h)


Lesenswert?

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
Noch kein Account? Hier anmelden.