Upgrade der Benutzeranwendung mit benutzerdefiniertem Bootloader über UART (STM32)

Ich verwende ein STM32L4-Board und mein Flash-Speicher sieht so aus:

|______________
|
| USER-Anwendung
|
|
|______________
|Vektortabelle(UA)
|______________ 0x8000 - 8000
|
| Benutzerdefinierter Bootloader
|
|
|______________
|Vektortabelle (BL)
|______________ 0x8000 - 0000

Mein Board ist über UART mit einem anderen Board verbunden (definieren wir das andere Board als Master und mein Board als Slave).
Das Master-Board muss in der Lage sein, die Benutzeranwendung des Slave-Boards über UART zu aktualisieren. Die Idee ist, eine Binärdatei über UART zu senden und in den Benutzeranwendungsbereich zu schreiben.

Laut dem Anwendungshinweis von ST gibt es einen Befehl namens Write Memory Command:

Der Write-Memory-Befehl wird verwendet, um Daten an eine beliebige gültige Speicheradresse zu schreiben (siehe Hinweis unten), dh RAM, Flash-Speicher, Optionsbytebereich.
Wenn der Bootloader den Write-Memory-Befehl empfängt, überträgt er das ACK-Byte an die Anwendung. Nach dem Senden des ACK-Bytes wartet der Bootloader auf eine Adresse (4 Bytes, Byte 1 ist das MSB der Adresse und Byte 4 ist das LSB) und ein Prüfsummenbyte und prüft dann die empfangene Adresse. Für den Optionsbyte-Bereich muss die Startadresse die Basisadresse des Optionsbyte-Bereichs sein (siehe Hinweis), um ein unpassendes Schreiben in diesen Bereich zu vermeiden.

wenn die empfangene Adresse gültig und die Prüfsumme korrekt ist, sendet der Bootloader ein ACK-Byte, andernfalls sendet er ein NACK-Byte und bricht den Befehl ab. Wenn die Adresse gültig und die Prüfsumme korrekt ist, führt der Bootloader Folgendes aus:

• erhält ein Byte N, das die Anzahl der zu empfangenden Datenbytes enthält

• erhält die Nutzdaten ((N + 1) Bytes) und die Prüfsumme (XOR von N und allen Datenbytes)

• Programmiert die Benutzerdaten ab der empfangenen Adresse in den Speicher

• am Ende des Befehls, wenn der Schreibvorgang erfolgreich war, sendet der Bootloader das ACK-Byte; andernfalls sendet er ein NACK-Byte an die Anwendung und bricht den Befehl ab

• Die maximale Länge des zu schreibenden Blocks für das STM32 beträgt 256 Byte

Dies bedeutet, dass ich nur 256 Bytes durch ein Paket aktualisieren kann, das von der Master-Karte zur Slave-Karte kommt.

Nehmen wir nun an, dass das Masterboard eine SD-Karte hat, die eine Binärdatei enthält, und ich möchte diese Datei in den Benutzeranwendungsbereich flashen. Wie kann ich das machen? Soll die Binärdatei gelesen und eine Reihe von 256 Bytes gesendet werden, jeweils 256 in einem Paket?

Antworten (2)

Ja. Natürlich können Sie mehrere Pakete senden.

Es gibt einen Kompromiss zwischen Effizienz und den Kosten, wenn ein Paket falsch geliefert wird. Bei kleinen Paketen gibt es insgesamt mehr Overhead für die tatsächlich gelieferte Datenmenge. Tritt jedoch ein Fehler auf, müssen weniger Daten erneut gesendet werden.

Trotzdem sind Datenfehler selten, oder sollten es zumindest sein. Im Allgemeinen senden Sie Pakete mit maximaler Größe, bis weniger als ein vollständiges Datenpaket übrig ist.

Ihr Prüfsummenalgorithmus ist eher ein Witz, sagen wir bestenfalls "primitiv". Kleinere Pakete haben einen besseren Prüfsummenschutz, da effektiv mehr Prüfsummenbits pro Datenbit vorhanden sind.

Natürlich bleiben Sie nicht bei diesem Bootloader hängen. Sie können einen schreiben, der tut, was Sie wollen. Weitere Informationen zu Bootloadern im Allgemeinen finden Sie in dieser Frage .

Mehr zur Verifizierung

Wie Peter in einem Kommentar betonte, ist die Korrektheit der Daten in einem Bootloader von entscheidender Bedeutung.

Das ist ein gutes Argument dafür, diesen Bootloader und seinen lächerlich naiven Prüfsummenalgorithmus aufzugeben. Was ich normalerweise tue, ist nicht einmal zu versuchen, einzelne Pakete zu prüfen. Ich entwerfe das Protokoll für eine angemessene Effizienz, füge dem gesamten Bild jedoch eine gute Prüfsumme hinzu.

Die Übertragung der Daten vom Host zum Gerät ist nur ein Teil des Problems. Anschließend muss es korrekt in den nichtflüchtigen Speicher geschrieben werden. Das ist eigentlich viel wahrscheinlicher zu scheitern. Ein Stromausfall oder der Benutzer, der zu einem ungünstigen Zeitpunkt auf die Reset-Taste drückt, kann beispielsweise zu Beschädigungen führen.

Meine Strategie ist generell, sich nicht um mögliche Fehler in einzelnen Prozessschritten zu kümmern, sondern das Endergebnis zu verifizieren. Normalerweise setze ich so etwas wie eine 24- oder 32-Bit-CRC-Prüfsumme an das Ende des hochgeladenen Bildes. Bevor der Bootloader die Haupt-App ausführt, überprüft er die Prüfsumme. Wenn es fehlschlägt, fordert es ein neues Bild an, führt das vorherige Bild aus, signalisiert einen Fehler oder so etwas. Führen Sie niemals ein beschädigtes Image aus.

Aus einem Kommentar:

Die Binärdatei enthält eine Firmware (einige .c und .h und Bibliotheken, die mit einer eingebetteten IDE wie Keil generiert wurden). Wie fügt man diese Prüfsumme zum Bild selbst hinzu? Ist es sicher, eine solche Datei zu ändern?

Nein, die Binärdatei enthält keine .c- und .h-Dateien. Es ist eine Binärdatei . Sie müssen einen Schritt zurücktreten und lernen, was der Compiler, der Bibliothekar und der Linker jeweils tun und welche Art von Informationen in den verschiedenen Dateitypen enthalten sind. Sie können keinen Code entwickeln, in dem Sie nahe an der Hardware sind, ohne diese Dinge zu verstehen.

Das Hinzufügen der Prüfsumme zur Binärdatei (häufig im Intel-Hex-Format) ist eine Möglichkeit, dem Bild eine Prüfsumme hinzuzufügen. Sie könnten ein separates Tool schreiben, das nach dem Linker ausgeführt wird. Dieses Tool liest das Bild, berechnet die Prüfsumme und bettet sie an bekannter Stelle wieder in das Bild ein.

Eine andere Möglichkeit besteht darin, das Uploader-Programm die Prüfsumme spontan hinzufügen zu lassen. Der Uploader liest die unveränderte Binärdatei und fügt die Prüfsumme an den bekannten Stellen hinzu, normalerweise den letzten paar Bytes des Bildes. Dieses modifizierte Image wird dann an den Bootloader gesendet, aber die Binärdatei wird nie verändert.

Effizienz ist nicht das Hauptproblem, wenn Sie die Firmware aktualisieren. Die Richtigkeit der Daten ist
Korrigieren Sie mich, wenn ich falsch liege, ich nehme das Binärbild, ich schicke es Paket für Paket bis zum letzten Teil davon. Sobald ich fertig bin, sende ich mir einen 32-Bit-CRC der Binärdatei und überprüfe, ob er mit dem berechneten in meinem Board übereinstimmt.
Sie können die Korrektheit jederzeit überprüfen, indem Sie die programmierten Daten zurücklesen. Dies würde auch nach Flash-Programmierfehlern suchen, anstatt nur die Kommunikation zu überprüfen. Ich würde auf jeden Fall den ROM-Bootloader weiterhin verwenden, da er auch dann verfügbar bleibt, wenn Sie versehentlich den gesamten Flash löschen.
@Pryda: Ich denke, es ist besser, eine Prüfsumme direkt in das hochgeladene Bild selbst einzubetten. Auf diese Weise kann die Korrektheit des Images immer überprüft werden, nicht nur zu dem Zeitpunkt, zu dem der Bootloader mit dem Host kommuniziert.
Olaf. Normalerweise führe ich die doppelte Überprüfung durch. Die Bildprüfsumme ist ein Teil des Bildes. Die Übertragungsprüfsumme ist etwas obendrauf. Normalerweise (heute eigentlich immer) verschlüssele ich das Bild auch.
Ist es normal, mit einer generierten Binärdatei herumzuspielen? Die Binärdatei enthält eine Firmware (einige .c und .h und Bibliotheken, die mit einer eingebetteten IDE wie Keil generiert wurden). Wie fügt man diese Prüfsumme zum Bild selbst hinzu? Ist es sicher, eine solche Datei zu ändern?

Sie möchten Ihren eigenen Bootloader schreiben, aber Sie zitieren den App-Hinweis für den integrierten. Vergiss diesen.

Schreiben Sie den Bootloader und lesen Sie nur das Referenzhandbuch. Vergessen Sie den eingebauten Bootlader und seine "Befehle"