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
Jeder Bootlader funktioniert so, seit Ewigkeiten.
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
Ein blöder Witz, ich weiss, aber könntest Du bitte auch das Rad nochmal erfinden?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.