Forum: Mikrocontroller und Digitale Elektronik STM32 - Firmeware flashen im laufenden Betreib - Kann das so funktionieren?


von Max (Gast)


Lesenswert?

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

von Georg G. (df2au)


Lesenswert?

Jeder Bootlader funktioniert so, seit Ewigkeiten.

von Stefan K. (stefan64)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

Ein blöder Witz, ich weiss, aber könntest Du bitte auch das Rad nochmal 
erfinden?

von Steffen R. (steffen_rose)


Lesenswert?

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.

von Steffen R. (steffen_rose)


Lesenswert?

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.

von Max (Gast)


Lesenswert?

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")

von Stefan K. (stefan64)


Lesenswert?

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

von Steffen R. (steffen_rose)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.