Hallo zusammen,
ich möchte gerne auf einem STM32F1 eine neue Firmware im laufenden
Betrieb flashen, ohne Bootpins.
Dazu habe ich mir folgendes Überlegt, und möchte gerne eure Meinung dazu
wissen, ob es so funktionieren könnte.
Meine Überlegung:
Das Erste Programm
- Ich erstelle ein ganz normales Programm
- In diesem Programm erstelle ich eine neue Sektion
("section_write_firmware")
-- In diese Sektion kommt die Logik für das Überspielen und schreiben
der Firmware
-- Diese Sektion kommt an das Ende vom Flash, definiert via.
Linkerscript
- Das eigentliche Programm, händelt den Funktionsaufruf von der
"section_write_firmware" (wenn der Befehl von außen kommt)
- Das Fertige (das erste Programm) wird wieder SWD auf den STM32
übertragen.
Die Section "section_write_firmware"
- Diese Funktion händelt den Transfer der Firmware und überschreibt den
Flash mit der neusten Firmware (bis zu der Sektion
"section_write_firmware" diese wird nicht überschrieben)
- Jegliche Interrupts werden deaktiviert
- Es werden keine Funktionsaufrufe außerhalt der Sektion aufgerufen
- Nach Abschluss des flashens wird ein System-Reset durchgeführt
Die weiteren Programme (die ich dann flashen möchte)
- Das Programm wird wie das erste Programm erstellt und ruft die
"section_write_firmware" auf
- Aber die Selektion "section_write_firmware" wird nicht gelinkt (d.h.
die fliegt aus dem Linkerscript raus, da sie ja schon im ersten Programm
enthalten war und nicht überschrieben wurde)
Könnte das so funktionieren oder ist mein Ansatz völlig falsch?
Vielen Dank und fröhliche Weihnachten
Max
Warum benutzt Du kein "normales" Bootloader-Konzept?
Was passiert bei Deinem Konzept, wenn es einen Fehler gibt, z.B. bei der
Übertragung? danach gibt es kein Programm mehr, daß Deine
Update-Routinen starten kann ..
Gruß, Stefan
Max schrieb:> -- Diese Sektion kommt an das Ende vom Flash, definiert via.> Linkerscript
Damit das Überspielen bei einem Fehler erneut angestoßen werden kann,
muss der Transfercode (Bootloader) eigenständig und aus dem Reset heraus
funktionieren.
Möchte man dies aus irgendeinem Grund nicht, sollte man den alternativen
Weg über den CPU internen Bootloader oder über SWD/Jtag offen halten.
Dies ist im Normalfall aber nicht gewollt.
Max schrieb:> - Es werden keine Funktionsaufrufe außerhalt der Sektion aufgerufen
Hierzu noch: Dieser Punkt ist nicht so einfach, wie er klingt. Wenn man
Pech hat meint der Optimierer, eine gemeinsame Codesequenz außerhalb
dieser Sektion aufrufen zu können.
Erst einmal vielen Dank für eure zahlreichen Posts zum frühen Morgen.
Was ich noch erwähnen sollte: Die Verbindung zu dem STM erfolgt über
Funk mit Authentifizierung.
Stefan K. schrieb:> Warum benutzt Du kein "normales" Bootloader-Konzept?> Was passiert bei Deinem Konzept, wenn es einen Fehler gibt, z.B. bei der> Übertragung? danach gibt es kein Programm mehr, daß Deine> Update-Routinen starten kann ..>> Gruß, Stefan
Was ist denn ein normales Bootloader Konzept? Der interne STM-Bootloader
braucht ja die Bootpins, das möchte ich vermeiden (da nicht möglich).
Die Verbindung zu dem STM32 erfolgt über Funk, daher möchte ich den
Bootloader nicht beim Reset ausführen, da es relativ viel Zeit braucht
bis der Funk-Chip initialisiert und Betriebsbereit ist. Des Weiteren
müsste ich dann ein Teil des Protokolls im Bootloader implementieren
(Authentifizierung usw., das will ich eigentlich nur im Hauptprogramm
haben)
Ich wollte die Daten Seitenweise mit CRC Prüfsumme übertragen, wenn ein
Fehler auftritt muss der Datensatz neu übertragen werden. Klar wenn es
ein Stromausfall gibt oder die Verbindung dauerhaft abreist, ist er
"remote" nicht mehr zu retten.
Klaus schrieb:> Ein blöder Witz, ich weiss, aber könntest Du bitte auch das Rad> nochmal> erfinden?
Das hatte ich eigentlich nicht vor. Ich wollte nur eine Lösung für mein
Problem finden.
Steffen R. schrieb:> Max schrieb:>> - Es werden keine Funktionsaufrufe außerhalt der Sektion aufgerufen>> Hierzu noch: Dieser Punkt ist nicht so einfach, wie er klingt. Wenn man> Pech hat meint der Optimierer, eine gemeinsame Codesequenz außerhalb> dieser Sektion aufrufen zu können.
Ah okay vielen Dank für den Hinweis, dass hatte ich noch nicht bedacht.
Gibt es da eventuell Compiler-Flags um das zu verhindern (GCC) bezogen
nur auf die eine Sektion.
Eventuell geht sogar: #pragma GCC optimize ("O0")
Max schrieb:> Was ist denn ein normales Bootloader Konzept?
Ein Bootloader zeichnet sich dadurch aus, daß er nach einem Reset als
Erster die Kontroller übernimmt und erst später an die eigendliche
Applikation übergibt. Das Konzept von ST mit den Bootpins ist da schon
eine Spezialisierung.
Denkbar ist z.B., daß der Bootloader eine CRC über das Appl-Flash
rechnet und nur bei Korrektheit die Appl startet. Bei einem Fehler
stellt der Bootloader selbstständig die Kommunikation her, um ein
erneutes Flashen zu ermöglichen.
Max schrieb:> Klar wenn es ein Stromausfall gibt oder die Verbindung dauerhaft abreist, > ist
er "remote" nicht mehr zu retten.
Ob das akzeptabel ist, hängt doch immer vom Anwendungsfall ab. Falls das
für Dich bedeutet, daß Du dann statt einem Remote-Update ein Kabel an
Deinen Robo anstecken musst: kein Problem, würde ich auch so machen ...
Wenn Du allerdings einen Techniker innerhalb von 24h nach New-York
schicken musst, weil das remote-Update einer Aufzugskabine
schiefgegangen ist, dann lohnt es sicher, sich ein paar Gedanken über
das Fehlerhandling beim Update zu machen.
Viele Grüße, Stefan
Max schrieb:> Steffen R. schrieb:>> Max schrieb:>>> - Es werden keine Funktionsaufrufe außerhalt der Sektion aufgerufen>>>> Hierzu noch: Dieser Punkt ist nicht so einfach, wie er klingt. Wenn man>> Pech hat meint der Optimierer, eine gemeinsame Codesequenz außerhalb>> dieser Sektion aufrufen zu können.>> Ah okay vielen Dank für den Hinweis, dass hatte ich noch nicht bedacht.> Gibt es da eventuell Compiler-Flags um das zu verhindern (GCC) bezogen> nur auf die eine Sektion.> Eventuell geht sogar: #pragma GCC optimize ("O0")
Wenn das Update mehr macht als nur umkopieren (z.B. vom externen Flash,
wohin per Funk die Daten zwischengeparkt wurden), wird der Bootloader
als eigenständiges Programm entwickelt. Damit ist er dann komplett
unabhängig.
Max schrieb:> Ah okay vielen Dank für den Hinweis, dass hatte ich noch nicht bedacht.> Gibt es da eventuell Compiler-Flags um das zu verhindern (GCC) bezogen> nur auf die eine Sektion.> Eventuell geht sogar: #pragma GCC optimize ("O0")
Einfach den Bootloader seperat kompilieren/linken.
Leider kann der STM32F1 nicht gleichzeitig aus dem Flash lesen und
Schreiben. Somit kannst du nicht gleichzeitig direkt den Bootloader
ausführen und flashen (es sei denn es ist akzeptabel dass der Bus und
die CPU blockiert werden); du musst den Bootloader bei dessen Start in
den RAM kopieren und von dort ausführen. So kannst du sogar den
Bootloader im Flash selber aktualisieren falls gewünscht.