ESP32S3 USB-OTG Zugriff auf Handydaten

OP #7629291
Lesenswert?

Hallo zusammen,

im Rahmen meines Projektes möchte ich einen ESP32S3 WROOM1 oder Mini1 mit einem Handy kommunizieren lassen. Die Kommunikation nutzt eine USB OTG Schnittstelle. Bislang ist es mir unklar, wie der ESP32 Zugriff auf Handydaten hat bzw. ob das Handy eine Binärdatei direkt auf dem Flash Speicher von ESP schreiben kann. Hintergrund ist es, es soll eine Firmware in Form einer Binärdatei auf dem Handy gespeichert und diese an den ESP32 geschickt werden, sodass der Bootloader sie beim Neustart ausführt und somit ein neues Firmware Image geflasht werden.(Flashen übers Handy und nicht über PC)

Meine Fragen:

  • kann der ESP32S3 auf die Binärdatei, die auf dem Handy gespeichert ist, zugreifen ? wenn ja, wie ?

  • Kann das Handy als Host die Datei direkt auf dem Flash Speicher schreiben. Das wäre die günstigste Lösung.

Gruss Ayman

#7629307
Lesenswert?

Ayman schrieb:

Die Kommunikation nutzt eine USB OTG Schnittstelle.

Kann Dein ESP32 sich als USB-Host verhalten, d.h. könntest Du an den auch einen USB-Stick anschließen?

Ayman schrieb:

Bislang ist es mir unklar, wie der ESP32 Zugriff auf Handydaten hat bzw. ob das Handy eine Binärdatei direkt auf dem Flash Speicher von ESP schreiben kann.

Kommt aufs "Handy" an. Smartphones können üblicherweise auf angeschlossene USB-Massenspeicher zugreifen, das können sogar die sonst recht gut verrammelten iOS-Geräte von Apple.

"Direkt auf den Flash Speicher" des ESP32 aber kann ein Smartphone auch nicht zugreifen, der ESP32 muss sich als USB-Mass Storage Device verkaufen, damit das geht. Und zusätzlich muss der ESP32 einen Dateisystemtreiber haben, über den er dann lesend auf seinen Speicher zugreift.

Welches Problem willst Du /eigentlich/ lösen?

OP #7629323
Lesenswert?

Zunächst vielen Dank für die schnelle Antwort.

Harald K. schrieb:

Kann Dein ESP32 sich als USB-Host verhalten, d.h. könntest Du an den auch einen USB-Stick anschließen?

Der ESP32 verfügt über eine USB-Host Bibliothek, die man einbinden kann. Zudem hat er eine integrierte USB-OTG Peripherie. D.h. der kann sich als Host verhalten.

Harald K. schrieb:

"Direkt auf den Flash Speicher" des ESP32 aber kann ein Smartphone auch nicht zugreifen, der ESP32 muss sich als USB-Mass Storage Device verkaufen, damit das geht. Und zusätzlich muss der ESP32 einen Dateisystemtreiber haben, über den er dann lesend auf seinen Speicher zugreift.

Welches Problem willst Du /eigentlich/ lösen?

OK. Dann bleibt die einzige Lösung, dass der ESP32 als Host auf die Datei zugreifen muss, die sich auf dem Smartphone (iOS oder Android) befindet. Das Problem besteht darin, wie der ESP32 darauf zugreifen kann? Welche Vorgehensweise und weitere Anforderungen gibt es denn ? Wie ich dich verstanden habe, muss der ESP32 dann die Datei lesen und selbst auf seinen eigenen Flash Speicher schreiben.

#7629326
Lesenswert?

Ayman schrieb:

Das Problem besteht darin, wie der ESP32 darauf zugreifen kann?

Du wirst via USB nicht auf das Dateisystem eines iOS-Gerätes zugreifen können. Das ist einfach nicht vorgesehen.

Bei Android kann es möglich sein, auf bestimmte Teile des Dateisystems zugreifen zu können.

Nochmal: Welches Problem willst Du /eigentlich/ lösen? Wozu soll das ganze gut sein?

Persönliche Seite #7629338
Lesenswert?

Hmmm schrieb:

Smartphone als Host, ESP als USB-CDC, die App kommuniziert dann seriell damit.

Das kann der ESP32-S3 sogar von sich aus; durch Setzen der Strapping-Pins kann man den Bootloader betreten. Das CDC ist auf dem ESP32S3 in Hardware implementiert, keine externe Hardware/VCP nötig. Dann braucht man nur noch eine App, welche dieses Protokoll spricht.

Man kann aber auch ein Custom USB-Protokoll (ohne CDC) implementieren:

  • ESP32S3 agiert als gewöhnliches Device
  • ESP32S3 empfängt ein Image über einen USB-Endpoint und flasht sich selbst (das ist dank ESP-IDF überraschend einfach)
  • Unter Android kann man in der App über android.hardware.usb.UsbManager auf das Gerät zugreifen, Daten austauschen und eben auch das Image senden

Vorteile:

  • "Sauberer" und schneller (IIRC)
  • Erspart die Fummelei mit Strapping-Pins und ggf. dafür vorzusehende Buttons
  • Daher benutzerfreundlicher
  • Man kann sogar gleichzeitig flashen/updaten und die normale Anwendung/Übertragung laufen lassen

Nachteile:

  • Größerer Implementationsaufwand
  • USB VID benötigt
  • Falls die Anwendung "gebrickt" ist kann man dann so nicht mehr flashen, das ist aber dank A/B-Updates (von ESP-IDF fertig implementiert) sehr unwahrscheinlich

Ganz andere Alternative: ESP32S3 verbindet sich per WiFi mit dem Internet, lädt das Update selbst herunter und updated sich selbst vollautomatisch.

Harald K. schrieb:

Bei Android kann es möglich sein, auf bestimmte Teile des Dateisystems zugreifen zu können.

Prinzipiell möglich über MTP, allerdings sehr umständlich. Das Dateisystem kann bei jedem Gerät anders organisiert sein. Kaum benutzerfreundlich, weil der Dateiname- und Ort exakt eingehalten werden muss. Außerdem ist USB-Host auf dem ESP32S3 komplex zu implementieren. Zukünftige Android-Versionen könnten den Zugriff weiter einschränken / unmöglich machen. Außerdem muss der Nutzer dem Gerät weitgehend vertrauen.

OP #7629347
Lesenswert?

Niklas G. schrieb:

Das kann der ESP32-S3 sogar von sich aus; durch Setzen der Strapping-Pins kann man den Bootloader betreten. Das CDC ist auf dem ESP32S3 in Hardware implementiert, keine externe Hardware/VCP nötig. Dann braucht man nur noch eine App, welche dieses Protokoll spricht.

Wenn du auf hilfreiche Quellen referenzieren oder mehr dazu sagen kannst, wäre das sehr nett.

Man kann aber auch ein Custom USB-Protokoll (ohne CDC) implementieren: Nachteile:

  • Größerer Implementationsaufwand
  • USB VID benötigt
  • Falls die Anwendung "gebrickt" ist kann man dann so nicht mehr flashen, das ist aber dank A/B-Updates (von ESP-IDF fertig implementiert) sehr unwahrscheinlich

Wie schaut es aus, wenn man den Flash Speicher in /factory/ und anderer Speicherort aufteilt, sodass man immer eine Reserve auf /factory/ hat und das neue Image auf dem neuen Speicherort geschrieben wird ?

Ganz andere Alternative: ESP32S3 verbindet sich per WiFi mit dem Internet, lädt das Update selbst herunter und updated sich selbst vollautomatisch.

Ja das ist mit Abstand die bessere Lösung. Leider ist es als Anforderung, dass der ESP32 über eine USB-Schnittstelle geupdatet wird.

Persönliche Seite #7629363
Lesenswert?

Ayman schrieb:

Wenn du auf hilfreiche Quellen referenzieren oder mehr dazu sagen kannst, wäre das sehr nett.

https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-guides/usb-serial-jtag-console.html

ESP32S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf

  • Kapitel "2.6 Strapping Pins"
  • Kapitel "3.5.12 USB Serial/JTAG Controller"

ESP32S3 Technical Reference Manual: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf

  • Kapitel "8 Chip Boot Control"
  • Kapitel "33 USB Serial/JTAG Controller (USB_SERIAL_JTAG)"

Ayman schrieb:

Wie schaut es aus, wenn man den Flash Speicher in factory und anderer Speicherort aufteilt

Nennt sich A/B Updates, kann das ESP-IDF von Haus aus, man muss nur das API nutzen:

Ayman schrieb:

Update der Firmware. Das neue Firmware Image wird als Biary Datei auf dem Smartphone gespeichert

Muss es unbedingt eine Datei sein? Ich habe genau so etwas mal mit dem ESP32S3 implementiert, mit einem Custom USB Protokoll wie erläutert. Auf Android-Seite war es eine App, welche das Image aus dem Web heruntergeladen hat in den RAM (einfach ein binäres ByteArray) und dann per USB rausgeschrieben. Erspart die Fummelei mit Dateizugriff-Permissions usw. Die paar Megabyte passen locker in den RAM moderner Smartphones.

Ayman schrieb:

Ja das ist mit Abstand die bessere Lösung. Leider ist es als Anforderung, dass der ESP32 über eine USB-Schnittstelle geupdatet wird.

Per HTTP/Internet wäre es praktisch schon fertig: https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32s3/api-reference/system/esp_https_ota.html

OP #7629367
Lesenswert?

Muss es unbedingt eine Datei sein? Ich habe genau so etwas mal mit dem ESP32S3 implementiert, mit einem Custom USB Protokoll wie erläutert. Auf Android-Seite war es eine App, welche das Image aus dem Web heruntergeladen hat in den RAM (einfach ein binäres ByteArray) und dann per USB rausgeschrieben. Erspart die Fummelei mit Dateizugriff-Permissions usw. Die paar Megabyte passen locker in den RAM moderner Smartphones.

Nein muss nicht. Könntest du auch paar Quellen dazu erwähnen ? Ich danke dir sehr

#7629373
Lesenswert?

Niklas G. schrieb:

Muss es unbedingt eine Datei sein? Ich habe genau so etwas mal mit dem ESP32S3 implementiert, mit einem Custom USB Protokoll wie erläutert. Auf Android-Seite war es eine App, welche das Image aus dem Web heruntergeladen hat in den RAM (einfach ein binäres ByteArray) und dann per USB rausgeschrieben.

Das geht dann aber erst recht nur mit Android. Unter iOS verweigert einem Apple den dafür nötigen Zugriff auf die USB-Schnittstelle.

Was universell möglich wäre, genügend Speicher auf Seiten des ESP32 vorausgesetzt, wäre die Implementierung eines "Mass Storage Device" auf dem ESP32.

Der verhält sich dann wie ein USB-Stick, das bedeutet, jedes beliebige Gerät, mit dem man USB-Sticks verwenden kann, kann darauf zugreifen.

Und das Firmwareupdate besteht dann darin, daß das Gerät, an das man den ESP32 anschließt, einfach eine Datei auf das Dateisystem des ESP32 kopiert.

Das nämlich geht mit Android, mit iOS oder mit jedem beliebigen PC.

Der ESP32 muss dafür halt die USB-Geräteklasse "Mass Storage Device" implementieren, einen ausreichend großen Speicher zur Verfügung stellen, der mit einer passenden FAT-Variante formatiert ist (FAT12 sollte reichen), und in der Lage sein, sich die fertig geschriebene Datei da rauszuholen.

So etwas kann sogar mit viel kleineren µCs umgesetzt werden, so etwas geht schon mit einem MSP430FR5529 (https://www.ti.com/tool/MSP-EXP430F5529LP).

Persönliche Seite #7629380
Lesenswert?

Harald K. schrieb:

Was universell möglich wäre, genügend Speicher auf Seiten des ESP32 vorausgesetzt, wäre die Implementierung eines "Mass Storage Device" auf dem ESP32.

Ja, geht grundsätzlich, finde ich aber keine besonders schöne/benutzerfreundliche Lösung. Lässt sich auch nicht gut automatisieren, man bekommt kein Feedback. Ich würde es auch eher als MTP und nicht als MSC machen, weil man sonst ein FAT32 simulieren müsste.

#7629390
Lesenswert?

Niklas G. schrieb:

Ich würde es auch eher als MTP und nicht als MSC machen

Die MTP-Unterstützung von iOS und macOS soll nicht die beste sein.

Was heißt "keine Rückmeldung"?

Mir sind schon Geräte untergekommen, die genauso ihr Firmwareupdate veranstalten, und die eine Textdatei in ihrem Dateisystem ablegen, in der die jeweils aktuelle Firmwareversion drinsteht.

Ein Beispiel ist das hier:

https://viltroxstore.com/pages/viltrox-firmware-update

Und da steckt ein Klon des ST23F103 drin (APM32F103CBT6 von "Geehy").

#7629406
Lesenswert?

Niklas G. schrieb:

Man kann nicht gut den Erfolg/Misserfolg/Fehlercode/Fortschritt an die Anwendung zurückmelden.

Wenn man eigens eine Anwendung auf dem Smartphone hat, dann geht das beim Verfahren des Objektivherstellers* sehr wohl, nämlich durch Auswertung der vom Objektiv im Dateisystem erzeugten Textdatei.

Vor dem Versuch des Firmwareupdates wird sie gelesen und die aktuelle Version bestimmt.

Nach dem Versuch des Firmwareupdates wird sie wieder gelesen und die Version bestimmt, die drinsteht.

*) Viltrox, s.o.

Persönliche Seite #7629412
Lesenswert?

Harald K. schrieb:

Wenn man eigens eine Anwendung auf dem Smartphone hat

... kann man auch gleich ein "richtiges" USB-Protokoll implementieren 😄 Auf dem Controller ist das definitiv weniger Aufwand...

Funktioniert das mit MSC überhaupt wenn das Image größer als der RAM vom Controller ist? Der Host kann die Cluster des Dateisystems ja in beliebiger Reihenfolge schreiben und überschreiben, und die Datei beliebig fragmentieren/in verdrehter Reihenfolge ablegen. Das müsste man ja erst puffern bevor und sortieren bevor man es in den Flash schreibt. Oder schreibt man alles in den Flash und sortiert nachträglich?

#7629423
Lesenswert?

Niklas G. schrieb:

... kann man auch gleich ein "richtiges" USB-Protokoll implementieren 😄

Kann man eben nicht, weil das unter iOS nicht möglich ist.

Niklas G. schrieb:

Funktioniert das mit MSC überhaupt wenn das Image größer als der RAM vom Controller ist?

Wenn man das Image im RAM ablegen will, geht das natürlich nicht.

Dann muss das Image halt direkt im Flash gespeichert werden.

Wenn man das aber schon mit so Popelcontrollern wie dem ST32F103 in den Griff bekommt, dann sollte es mit so einem Dickschiff wie dem ESP32 erst recht möglich sein.

Der ESP32-S3 hat 512 kB RAM; wie funktioniert das denn beim OTA-Update?

#7629465
Lesenswert?

Niklas G. schrieb:

Ist bei MSC halt nicht so.

Ließe sich aber durch Verwendung eines geeigneten Dateiformates lösen; wenn z.B. Intel-Hex o.ä. genutzt wird, dann ist die Adressierung recht eindeutig. Um auf zwei Cluster/Sektoren verteilte Zeilen zu umgehen, wäre auch ein Format denkbar, das Datenblöcke und Adresse in einem 512-Byte-Block unterbringt. Bei 32-Bit-Adressen passen somit 508 Nutzbytes in einen dieser Blöcke, und dann ist es wirklich völlig wurscht, in welcher Reihenfolge der Kram geschrieben wird.

Ganz so einfach sollte man es sich natürlich nicht machen, um Fehlzugriffe abzufangen, zusätzlich zur Adresse sollte noch ein "magic Word", eine Blocklänge und gegebenenfalls eine Prüfsumme verwendet werden, damit nicht jemand versehentlich ein Bild auf den ESP32 kopiert und der damit sein Flash plättet.

Damit ließen sich immer noch um die 500 Nutzbytes pro Block unterbringen.

Persönliche Seite #7629467
Lesenswert?

Harald K. schrieb:

Damit ließen sich immer noch um die 500 Nutzbytes pro Block unterbringen.

Und was wenn die Pagesize vom Flash größer als 500 ist, z.B. 512? Die "Sektoren" können ja in x-beliebiger Reihenfolge ankommen - man müsste also die Flash-Pages mehrfach beschreiben wenn die Sektoren, die zu einer Page gehören, mit großem Abstand ankommen. Und in RAM puffern kann man das gesamte Image auch nicht...

Ich würde iOS einfach nicht unterstützen, das ist ja offensichtlich für den professionellen Einsatz nicht geeignet!

#7629473
Lesenswert?

Niklas G. schrieb:

Und was wenn die Pagesize vom Flash größer als 500 ist, z.B. 512? Die "Sektoren" können ja in x-beliebiger Reihenfolge ankommen - man müsste also die Flash-Pages mehrfach beschreiben wenn die Sektoren, die zu einer Page gehören, mit großem Abstand ankommen. Und in RAM puffern kann man das gesamte Image auch nicht...

Da keine einzelnen Sektoren geschrieben werden, sondern i.d.R. mehrere auf einmal (sog. Cluster), sollte das kein wirkliches Problem sein. Das nötige Abstraktionsvermögen traue ich Dir zu.

Ich würde iOS einfach nicht unterstützen, das ist ja offensichtlich für den professionellen Einsatz nicht geeignet!

Warum eine "App" verwenden, wenn man einfach eine Datei draufkopieren kann?

Weil es den Anwender intellektuell überfordert, sich im Dateisystem den Inhalt einer Textdatei anzusehen? Sind wir schon so weit, daß man sich nach so grunzdummen Leuten richten muss? Die sind dann aber auch zu blöd, die "App" richtig zu bedienen.

Im übrigen halte ich Deine These, daß beim Kopieren einer Datei die Blöcke, aus denen die Datei besteht, in völlig stochastischer Reihenfolge übertragen werden, für ... interessant.

Hast Du das schon mal untersucht, von einem völlig leeren Dateisystem ausgehend?

Persönliche Seite #7629489
Lesenswert?

Harald K. schrieb:

Da keine einzelnen Sektoren geschrieben werden, sondern i.d.R. mehrere auf einmal (sog. Cluster),

Naja, "i.d.R." ist keine Garantie. Sich bei sowas auf "i.d.R." verlassen? Cluster existieren nur auf Dateisystemebene, der MSC-Treiber kennt nur einzelne Sektoren.

Harald K. schrieb:

Hast Du das schon mal untersucht, von einem völlig leeren Dateisystem ausgehend?

Selbst wenn es bei meinen Experimenten korrekt liefe, gibt es keine Garantie. Ein Produkt auf Hoffnung und "hat bisher immer geklappt" aufzubauen finde ich schwierig.

Harald K. schrieb:

Warum eine "App" verwenden, wenn man einfach eine Datei draufkopieren kann?

Die Anforderung riecht sehr nach Enterprise, da geht es eh um Automatisierung, da will man nicht manuell mit Dateien rumfummeln. Eine App kann das Cloud-Gesteuert automatisieren, mit Rückmeldung zum Cloud-Server usw.

#7629711
Lesenswert?

Niklas G. schrieb:

Selbst wenn es bei meinen Experimenten korrekt liefe, gibt es keine Garantie. Ein Produkt auf Hoffnung und "hat bisher immer geklappt" aufzubauen finde ich schwierig.

Sicher. Gewiss. Aber daß Dateien in stochastischer Reihenfolge geschrieben werden, das ist eine sehr hypothetische Annahme. Um von so etwas auszugehen, würde ich doch gerne mal einen Beleg dafür sehen, daß das /überhaupt/ irgendwo auftritt.

Fragmentierung kann in diesem Betriebsfall übrigens komplett ausgeschlossen werden, das Ziel-Dateisystem ist /leer/.

Aber die ganze Diskussion ist eh' müßig, denn die vom Esp32 verwendeten Flashpages sind 256 Byte groß, wie man https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/spiffs.html entnehmen kann.

Niklas G. schrieb:

Die Anforderung riecht sehr nach Enterprise

Also der übliche BWL-Schlipsträger-"Bullshit". Ja, dann kann man nichts machen. Und eine App, die eine Datei kopiert, und vorher bzw. nachher eine andere Datei liest und auswertet, die kann natürlich nichts in eine Cloud melden. Weil das ja klar ist.

Persönliche Seite #7629746
Lesenswert?

Harald K. schrieb:

Um von so etwas auszugehen, würde ich doch gerne mal einen Beleg dafür sehen, daß das überhaupt irgendwo auftritt.

Ich weiß dass morgen ein iPhone released wird welches in einer vom Gerät nicht vorhersehbaren aber nicht stochastischen Reihenfolge schreibt (z.B. immer jeder 3. Block).

Harald K. schrieb:

Fragmentierung kann in diesem Betriebsfall übrigens komplett ausgeschlossen werden, das Ziel-Dateisystem ist leer.

Der Treiber kann trotzdem fragmentieren wenn ihm danach ist.

Harald K. schrieb:

Aber die ganze Diskussion ist eh' müßig, denn die vom Esp32 verwendeten Flashpages sind 256 Byte groß

Ja, dann könnte es tatsächlich gehen wenn man pro 512B-Sektor 256B Nutzdaten verpackt und man mit Prüfsummen und Header sicherstellt dass man die Position korrekt erkennt. Ist nicht gerade effizient, was aber bei der Datenmenge relativ egal ist.

Harald K. schrieb:

Und eine App, die eine Datei kopiert, und vorher bzw. nachher eine andere Datei liest und auswertet, die kann natürlich nichts in eine Cloud melden. Weil das ja klar ist.

Wie kann die App eigentlich den FS-Cache invalidieren? Also wenn das Gerät initial angesteckt wird, ist der per Datei vermeldete Zustand auf "alte Firmware". Nach dem Flashen simuliert das Gerät in der Datei einen neuen Zustand. Der Treiber im Host-OS liest die Datei aber gar nicht mehr aus, sondern liefert aus dem Cache immer nur das "alt" an die App. Um das Cache-Invalidate zu forcieren müsste sich das Gerät neu enumerieren. In der App muss man dann genau aufpassen dass man auch wieder exakt das selbe Gerät erwischt und nicht einen USB-Stick der in der Zwischenzeit eingesteckt wurde.

Ja, alles irgendwie möglich, aber schon eine Frickellösung mit vielen "hat bisher immer geklappt"-Hoffnungen.

#7629755
Lesenswert?

Niklas G. schrieb:

Wie kann die App eigentlich den FS-Cache invalidieren? Also wenn das Gerät initial angesteckt wird, ist der per Datei vermeldete Zustand auf "alte Firmware". Nach dem Flashen simuliert das Gerät in der Datei einen neuen Zustand.

Ganz einfach: Das Gerät (nicht die App!) trennt sich beim Firmware-Update vom Host. Danach wird eine Neuverbindung ausgeführt, das ist also so, als würde man einen USB-Stick abziehen und wieder dranstöpseln.

Lies die von mir verlinkte Beschreibung der Updateprozedur von Viltrox, die machen das genau so.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren