Neues Feature: OTA-Update via WebGUI

In deinem Projektverzeichnis gibt es einen Unterordner .pio. Dort ist build drin und da findest du die firmware.

Ich hab mich jetzt noch einmal mit OTA beschäftigt und würde hier gerne noch einmal die Dinge zusammenfassen und um Unterstützung bitten:

OTA

  • Wenn OTA zur Verfügung steht (8 MB Flash), existieren zwei App-Partitionen im Flash-Speicher (OTA0 und OTA1).
  • Zusätzlich existiert eine OTA-Data-Partition, in welcher (u.a.) gespeichert wird, welche App-Partition gerade aktiv ist.
  • Bei einem OTA-Update wird die jeweils nicht verwendete OTA-Partition mit der neuen Software beschrieben und anschliessend wird diese als „aktiv“ markiert.
  • Nach eine Reboot wird die neue Software gestartet.
  • Das funktioniert immer im Wechsel und somit kann entweder OTA0 oder OTA1 die gerade aktive App-Partition sein,

OTA-Bug

  • Bei einem Update über USB/Seriell wird IMMER die App-Partition OTA0 beschrieben.
  • Wenn nun - durch vorherige OTA-Updates - OTA1 gerade die aktive App-Partition ist, wird weiterhin OTA1 gestartet.
  • Die per USB/Seriell aktualisierte Software wird nicht gestartet.

Lösungen

  • „Erase Flash“. Damit wird alles gelöscht (auch die OTA-Data-Partition) und somit auch wieder von OTA0 gestartet. Nachteil: Es wird alles gelöscht…
  • esptool.py erase_region 0x9000 0x2000 Löscht nur die OTA-Data-Partition. Wobei „0x9000“ evtl.angepasst werden muss. Das ist die Startadresse der OTA-Data-Partition.

To do:

  • Bei einem einfachen OTA Sketch (OTA Demo) tritt das Problem nicht auf. Dann wird (vom esptool) die aktive Partition wieder zurück auf OTA0 gesetzt.

    • esptool and OTA conflict - ESP32 Forum > As you’ve noticed, the default flasher commands in master branch now erase the ota_data partition and flash the default partition (factory or OTA slot 0 if no factory partition is present) each time. This will be in the V3.2 release.
    • Vermutung: Bei Verwendung einer angepassten Partitionskonfiguration (z.B. custom_8mb_ota.csv) wird die OTA-Data-Partition nicht angefasst.
  • PlatformIO „PreAction Script“ schreiben, um „erase_region“ automatisch ausführen zu lassen. OTADATA not reset on code upload for ESP32 - PlatformIO Community

    • Hier müsste man am besten prüfen, ob OTA verwendet wird und wenn ja, welche Adresse die OTA-Data-Partition hat.
  • Ich hab’ zum debuggen die Funktionen esp_ota_get_boot_partition() und esp_ota_get_running_partition() eingebunden. So kann man sehen, welche App-Partition gerade aktiv ist. → Könnte man auch im Web-UI anzeigen.

    • Man könnte im der Web-UI sogar die aktive Partition wechseln :face_with_raised_eyebrow:
  • Ergänzungen / Korrekturen / Vorschläge ? :smiley:

  • Python - Spezis hier um das PlatformIO Script zu erstellen?

1 „Gefällt mir“

Da rufe ich mal @fetzerch :slight_smile:

Sowas in etwa?

Ich nutze im Moment kein OTA. Gerne testen und feedback geben. Habe auch nichts dagegen, wenn jemand anders den PR übernimmt und fertig macht.

4 „Gefällt mir“

Danke @fetzerch - ich teste das gerne in dieser Woche.

1 „Gefällt mir“

Ich bin jetzt endlich dazu gekommen das zu testen.

Sieht in meiner Umgebung sehr gut aus! Die OTA Partition wird gelöscht und immer von der app0 gestartet.
Bei den beiden Todo’s im PR kann ich leider nicht helfen. Ich habe versucht den code in otatool.py zu verstehen. Ich würde meinen, dass vorab eine Prüfung stattfindet. Kann man das nicht so lassen?

Ich habe in diesem Zusammenhang noch ein paar Anpassungen für OTA gemacht:

Evtl. bekommt man damit auch die weiter oben beschriebenen Probleme in den Griff.
Es wird damit im Log (und in der WebUI unter Info) angezeigt, von welcher OTA-Partition gestartet wurde:

[ 586 ]  Software-revision: 20230108-1
[ 586 ]  Git-revision: 411d98a-dirty
[ 596 ]  ESP-IDF version: v4.4.3
[ 603 ]  OTA-Info: Running: app1 | Boot: app1 | Next-OTA: app0
1 „Gefällt mir“

Ich benutze meinen Espuino hauptsächlich als „Frühstücksradio“ . Dazu habe ich eine .m3u mit 10 Streams.
@biologist Ist es machbar beim Abspielen von m3u-Listen mittels der Tasten vor und zurück über die Endpunkte in beide Richtungen hinauszurollen ?
Ich meine von 1 ans Ende und vom Ende wieder zu 1. Das würde den Weg von z. Bsp. Antenne Bayern bis WDR2 deutlich verkürzen.
Ich weiß , langer Tastendruck geht auch…aber Faulheit und WAF.

Das müsste gehen, indem du in nachfolgendem Case noch die Zeile
gPlayProperties.repeatPlaylist = true; einfügst:

In diesem Fall sollte dann das hier greifen:

Prinzipiell geht es , aber manchmal ein Reboot

Rebooting…
ets Jul 29 2019 12:21:46

Inzwischen funktioniert das aber fehlerfrei, oder?
Ich gehe davon aus, dass der Reboot durch den Fehler mit der falschen LED-Adressierung (mitunter 255) passiert ist.

Ist ok, ich hatte nichts mehr

Ich habe das leider noch wie vor nicht getestet, aber werde schauen, dass ich das in der nächsten Woche endlich mal hinkriege. Ist auf jeden Fall wichtig, dass OTA stabil funktioniert.

Ich hatte gestern wieder diesen OTA-Bug. Ich habe dann den commit von @fetzerch installiert, klappte ausgezeichnet.
Damit kann ich leben , sind die 2 todo´s wichtig, ich kann das nicht einschätzen? Wäre schön wenn das in den Master kommt.

Ich kann schlecht einschätzen um welche inkompatible Hardware es sich handelt und was das Problem wäre, wenn das auf dieser Hardware angewendet wird.
Ich kann auch nur bestätigen, dass diese Änderung bei mir super funktioniert…

Ich denke es wäre halt gut, wenn wir die 2 von mir beschriebenen potentiellen Fehlerquellen ausschließen können.

Es bräuchte also jemanden, der den PR (platformio: Erase OTA partition before upload by fetzerch · Pull Request #190 · biologist79/ESPuino · GitHub) auf einem Board ohne OTA support testen könnte. Sollte das Pre-Upload-Script hier Probleme machen, dann müssen wir das in der platformio.ini eben nur bei Boardkonfigurationen eintragen die OTA unterstützen.

Das zweite Problem könnten auftreten, wenn jemand ein komplett frisches Devboard flasht. Da gibt es ja dann keine OTA Partition - und ich bin mir nicht sicher was dann passiert. Das könnte vielleicht am ehesten @biologist selbst probieren.

EDIT: Ein dritter Test wäre vielleicht ob das ganze unter Windows auch funktioniert.

Wenn das klappt können wir das Script dann auch nach master oder (vielleicht besser erstmal dev) mergen.

@fetzerch
1.Versuch
lolin32 ==> geht so nicht

Archiving .pio/build/lolin32/libFrameworkArduino.a
Indexing .pio/build/lolin32/libFrameworkArduino.a
Linking .pio/build/lolin32/firmware.elf
Retrieving maximum program size .pio/build/lolin32/firmware.elf
Checking size .pio/build/lolin32/firmware.elf
Advanced Memory Usage is available via „PlatformIO Home > Project Inspect“
RAM: [== ] 21.6% (used 70772 bytes from 327680 bytes)
Flash: [====== ] 58.9% (used 2277813 bytes from 3866624 bytes)
Building .pio/build/lolin32/firmware.bin
esptool.py v4.5
Creating esp32 image…
Merged 25 ELF sections
Successfully created esp32 image.
before_upload([„upload“], [„.pio/build/lolin32/firmware.bin“])
Performing pre-upload erase of OTA partition…
scons: *** [upload] CalledProcessError : Command ‚[‘/Users/willmar/.platformio/penv/bin/python’, ‚/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/esptool_py/esptool/esptool.py‘, ‚read_flash‘, ‚32768‘, ‚3072‘, ‚/var/folders/ft/m2nh_4gn1r33tr7swjh7_y840000gn/T/tmpc90zf2qi‘]’ returned non-zero exit status 2.
Traceback (most recent call last):
File „/Users/willmar/.platformio/packages/tool-scons/scons-local-4.4.0/SCons/Action.py“, line 1318, in execute
result = self.execfunction(target=target, source=rsources, env=env)
File „/Users/willmar/Documents/PlatformIO/Projects/ESPuino-dev_multi_03_04_2023/eraseOTA.py“, line 30, in before_upload
ota_target = OtatoolTarget(env.subst(„$UPLOAD_PORT“))
File „/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/app_update/otatool.py“, line 56, in init
self.target = ParttoolTarget(port, baud, partition_table_offset, partition_table_file, esptool_args,
File „/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/partition_table/parttool.py“, line 112, in init
self._call_esptool([„read_flash“, str(partition_table_offset), str(gen.MAX_PARTITION_LENGTH), temp_file.name])
File „/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/partition_table/parttool.py“, line 132, in _call_esptool
subprocess.check_call(esptool_args, stdout=null_file, stderr=null_file)
File „/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/subprocess.py“, line 369, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‚[‘/Users/willmar/.platformio/penv/bin/python’, ‚/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/esptool_py/esptool/esptool.py‘, ‚read_flash‘, ‚32768‘, ‚3072‘, ‚/var/folders/ft/m2nh_4gn1r33tr7swjh7_y840000gn/T/tmpc90zf2qi‘]’ returned non-zero exit status 2.
================================================================================ [FAILED] Took 71.09 seconds ================================================================================

Environment Status Duration


lolin32 FAILED 00:01:11.088
=========================================================================== 1 failed, 0 succeeded in 00:01:11.088 ===========================================================================

2. Versuch

ESP32-A1S (16MB) mit erase flash gelöscht , auch dann geht es nicht .

| |-- FS @ 2.0.0
|-- Preferences @ 2.0.0
Building in release mode
Compiling .pio/build/esp32-a1s/src/Web.cpp.o
Linking .pio/build/esp32-a1s/firmware.elf
Retrieving maximum program size .pio/build/esp32-a1s/firmware.elf
Checking size .pio/build/esp32-a1s/firmware.elf
Advanced Memory Usage is available via „PlatformIO Home > Project Inspect“
RAM: [== ] 21.4% (used 70108 bytes from 327680 bytes)
Flash: [=== ] 34.5% (used 2261217 bytes from 6553600 bytes)
Building .pio/build/esp32-a1s/firmware.bin
esptool.py v4.5
Creating esp32 image…
Merged 25 ELF sections
Successfully created esp32 image.
before_upload([„upload“], [„.pio/build/esp32-a1s/firmware.bin“])
Performing pre-upload erase of OTA partition…
*** [upload] Exception : No otadata partition found
Traceback (most recent call last):
File „/Users/willmar/.platformio/packages/tool-scons/scons-local-4.4.0/SCons/Action.py“, line 1318, in execute
result = self.execfunction(target=target, source=rsources, env=env)
File „/Users/willmar/Documents/PlatformIO/Projects/ESPuino-dev_multi_03_04_2023/eraseOTA.py“, line 31, in before_upload
ota_target.erase_otadata()
File „/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/app_update/otatool.py“, line 76, in erase_otadata
self._check_otadata_partition()
File „/Users/willmar/.platformio/packages/framework-espidf@3.40001.200521/components/app_update/otatool.py“, line 73, in _check_otadata_partition
raise Exception(„No otadata partition found“)
Exception: No otadata partition found
================================================================================ [FAILED] Took 46.59 seconds ================================================================================

Environment Status Duration


esp32-a1s FAILED 00:00:46.588
=========================================================================== 1 failed, 0 succeeded in 00:00:46.588 ===========================================================================

  • The terminal process „platformio ‚run‘, ‚–target‘, ‚upload‘, ‚–target‘, ‚monitor‘, ‚–environment‘, ‚esp32-a1s‘“ terminated with exit code: 1.
  • Terminal will be reused by tasks, press any key to close it.

:bangbang:
Fazit : wer es im Moment mit neuen ESP32 die noch keine OTA-Partition haben nutzen will muss die 2 Zeilen in platformio.ini für den 1. Flash deaktivieren. Bestehen die OTA-Partitionen schon geht es einwandfrei

1 „Gefällt mir“

Ich möchte dieses Thema hier nochmal in Erinnerung rufen.

Vielleicht wurde das Problem zwischenzeitlich auch anderweitig gelöst (durch Espressif).

Ich habe die letzte Zeit reichlich oft per OTA oder UART , ohne darauf zu achten, geflasht , es hat immer funktioniert.

2 „Gefällt mir“

Um nochmal diejenigen abzuholen, die sich noch nicht so lange mit ESPuino beschäftigen: Man kann, siehe erster Post, Firmwares auch über das Webinterface hochladen. Geht natürlich erst, wenn sich bereits ESPuino auf dem ESP befindet.

Dabei kam es in der Vergangenheit jedoch „immer mal wieder“ zu dem Problem, dass weiterhin die alte Firmware gebootet wurde und erneute OTA-Uploads das Problem auch nicht mehr beseitigt haben. Selbst reguläres Flashen hat dies (meines Wissens) nicht mehr geändert. Sicher kam man da nur wieder durch „Erase Flash“ und erneutes Flashen raus.

Und an dieser Stelle stellt sich jetzt die Frage, ob dieses Problem beim jetzt neuen Master noch eines ist.

Danke für den Hinweis! Hab’s gerade hin- und hergetestet, also ein/zwei/drei/vier mal OTA-Update, dann Upload über UART. Jedes Mal wird die richtige Firmware gebootet :+1:

Das Problem hat sich also von selbst erledigt, vermutlich über einen Bugfix in PlatformIO

1 „Gefällt mir“