Forum: Mikrocontroller und Digitale Elektronik Firmwareupdate STM32 per KNX


von Micha (michael_schwaer)


Lesenswert?

Hallo,

ich habe diverse Platinen, die ich ab und zu flashen möchte. Bei einigen 
Platinen ist es aufwändig, an die SWD-Schnittstelle ranzukommen. Es ist 
aber eine KNX-Verbindung vorhanden, die ich als Datenzugriff nutzen 
könnte. Die Platine hat einen STM32L452RET6TR, der vom Speicher nur 
geringfügig ausgelastet ist: Vom Flash sind aktuell 56 kB von 512 kB 
benutzt. Vom RAM sind ca. 120 kB von 128 kB frei.

Für die Kommunikation bei der Datenübertragung würde ich zwei 
KNX-Gruppenadressen verwenden:

* 14 Byte-Element für Adresse (4 Byte), Daten (9 Byte) und Checksumme (1 
Byte) zur Platine
* 1 Byte unsigned (ACK / NAK von der Platine)

Das 14-Byte-Element ist das größte, das es bei KNX gibt. Es wird 
normalerweise für die KNX-Übertragung von Text verwendet. Das 
zweitgrößte hätte 4 Byte.

Da vom RAM sehr viel frei ist, könnte ich den kompletten Inhalt des 
neuen Flash-Programms dort beim Übertragen zwischenspeichern. Wenn alles 
angekommen ist, den Flash mit den neuen Daten per HAL_FLASH_Program 
beschreiben und am Ende einen Reset auslösen.

Müsste doch prinzipiell so gehen?

Grüße
Micha

Beitrag #7802255 wurde vom Autor gelöscht.
von Gerd E. (robberknight)


Lesenswert?

Micha schrieb:
> Da vom RAM sehr viel frei ist, könnte ich den kompletten Inhalt des
> neuen Flash-Programms dort beim Übertragen zwischenspeichern. Wenn alles
> angekommen ist, den Flash mit den neuen Daten per HAL_FLASH_Program
> beschreiben und am Ende einen Reset auslösen.
>
> Müsste doch prinzipiell so gehen?

Ja, grundsätzlich schon.

Du musst allerdings aufpassen dass der Code, der hinterher die Daten aus 
dem RAM ins Flash schreibt, selbst komplett im RAM liegt.

Dafür müssen alle Funktionen in die richtige Section gelinkt werden. Es 
passiert auch dass der Compiler bei der Optimierung feststellt, dass es 
an manchen Stellen besser ist eine eingebaute Funktion wie memcpy 
aufzurufen - und die betrifft das mit dem RAM dann natürlich genauso.

Für sowas also hinterher das map-File genau anschauen. Evtl. fällt so 
ein Problem nämlich bei einem ersten Test nicht sofort auf wenn sich die 
beiden Versionen nicht allzusehr unterscheiden.

von Ron-Hardy G. (ron-hardy)


Lesenswert?

Und immer an Murphy denken: genau dann wenn du updatest fällt der Strom 
aus

von Micha (michael_schwaer)


Angehängte Dateien:

Lesenswert?

Gerd E. schrieb:
> Du musst allerdings aufpassen dass der Code, der hinterher die Daten aus
> dem RAM ins Flash schreibt, selbst komplett im RAM liegt.

Kann ich diesen Quellcode nicht an eine Stelle im Flash legen, die nie 
benutzt wird?
Die aktuelle HEX-Datei beginnt bei Adresse 0 und endet bei 0xDC9B. Ich 
könnte den entsprechenden Quellcode z.B. ab dem Bereich 0x20000 legen. 
Ich würde mir zuvor aber die neuen Hexfiles anschauen, wo die Bytes 
liegen.

von Gerd E. (robberknight)


Lesenswert?

Micha schrieb:
> Kann ich diesen Quellcode nicht an eine Stelle im Flash legen, die nie
> benutzt wird?

Klar, das geht auch.

Aber der Aufwand ist in etwa der selbe. Also section-Attribute setzen, 
Linkerscript bearbeiten, map-File prüfen etc. Und Du hast dann den 
Aufwand dass Du diesen einen Funktionsblock einmal an diese spezielle 
Stelle flashen musst und spätere Änderungen und Anpassungen daran 
schwieriger sind.

Da fände ich eine normale Funktion, die in jeder Firmware-Version 
enthalten ist, einfacher.

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

Ne andere Variante wäre der klassische Bootloader. Also ein Stück 
Firmware was alles nötige enthält, also KNX-Kommunikation, Prüfsumme und 
Schreiben ins Flash. Das ganze linkst Du einmal an eine Flash-Adresse 
die Du mit der normalen Firmware nicht verwendest.

Jetzt kannst Du entweder per Befehl in die spezielle Firmware springen. 
Oder oft macht es auch Sinn beim Boot immer erst mit dem Bootloader zu 
starten und dann z.B. nach einem Timeout in die normale Firmware zu 
springen. Dann kannst Du selbst aus einer nicht normal laufenden 
Firmware heraus etwas neues Flashen.

Vorteil im Vergleich zu den anderen Varianten ist auch der Aufwand: Du 
musst nicht mühsam section-Attribute verteilen, sondern einfach nur die 
Startadresse anpassen. Dabei natürlich auch die Adresse für die 
Interruptvektortabelle beachten.

von Frank K. (fchk)


Lesenswert?

Micha schrieb:
> Gerd E. schrieb:
>> Du musst allerdings aufpassen dass der Code, der hinterher die Daten aus
>> dem RAM ins Flash schreibt, selbst komplett im RAM liegt.
>
> Kann ich diesen Quellcode nicht an eine Stelle im Flash legen, die nie
> benutzt wird?

Nicht notwendigerweise. Beim Programmieren einer Page ist bei vielen 
Prozessoren das gesamte Flash nicht mehr zugreifbar. Da gibts dann einen 
separaten Block für den Bootloader, um dieses Problem zu vermeiden.

Deswegen packt man ja die Flashroutine an sich ins RAM, bei Cortex M am 
Besten ins ITCM. Das hat einen separaten, besonders schnellen Datenpfad, 
der völlig unabhängig vom Flash ist.

Es gibt auch Controller, die zwei unabhängige Flash-Bänke haben (Keyword 
"Dual Bank Flash" bei STM32), wo eine Bank den aktuell laufenden Code 
enthält und die andere eine Backup Firmware oder den zu flashenden Code. 
Mit einem Bit kann man die Bänke im Adressraum vertauschen. Das gibts 
auch bei STM32, und wenn Du dieses Feature möchtest, dann nimmst Du eben 
einen solchen Prozessor. Beispiel: STM32L475RE. Ich vermute mal, dass Du 
da an Deinem Design nicht viel ändern musst.

fchk

von Max G. (l0wside) Benutzerseite


Lesenswert?

Hallo Micha,

nachdem ich einige Jahre KNX-Geräte entwickelt und verkauft habe, kenne 
ich das Thema nur zu gut.

Für ein Update sind Gruppenadressen in der KNX-Systematik der falsche 
Ansatz, dafür dient eigentlich MemoryWrite mit direkter Adressierung des 
Geräts. Technisch möglich ist es natürlich. Verwendest du den Weinzierl 
BAOS-IC, hast du einen Stack gekauft, oder hast du einen Freeware-Stack 
verwendet?

KNX ist entsetzlich lahm, die Datenrate von 9.600 bit/s wird zu einem 
erheblichen Teil vom Overhead aufgefressen. 500-600 Byte/s sind halbwegs 
realistisch. Für 32 kB bist du also gut und gern eine Minute mit 
Datenübertragung beschäftigt. Das ist möglich, nervt aber gewaltig (auch 
und vor allem bei Entwicklung und Debuggen). Packen hilft, LZIP ist gar 
nicht so schwer zu implementieren. Irgendwo habe ich noch halbwegs 
funktionierenden Code dafür. Gib Bescheid, wenn du ihn haben willst.

Das Update im RAM zu speichern ist nur dann sinnvoll, wenn du dir sicher 
bist, dass das Gerät auch nach einem gescheiterten Update wieder 
hochkommt und kommuniziert. Das bedeutet praktisch, dass du den Stack 
selbst nie aktualisieren kannst und dass du auf dem Gerät nachher einen 
Hybrid aus alter und neuer Software hast. Das ist eklig in der 
Fehlersuche, und du wirst enge Freundschaft mit dem Linkerfile schließen 
müssen. Beispiel: Pointer in den Stack müssen auch in der neuen Software 
an die alten Adressen zeigen. Alles machbar, aber fummelig und blöd zu 
debuggen.

Meines Erachtens sinnvoller ist, die Update-Datei für die gesamte 
Software im Flash zu speichern und nach dem Reset zu schauen, ob dort 
etwas Brauchbares liegt. Checksummen/Signaturen sind da seeeehr 
hilfreich, um zum einen das Vorhandensein eines Updates und zum anderen 
seine Integrität zu prüfen. Dann brauchst du nur einen Bootloader, der 
immer konstant bleibt - weil der aber mit dem Rest des Programms nicht 
kommuniziert, kann da weniger schiefgehen. Wenn das Update scheitert, 
versucht das Gerät es einfach beim nächsten Booten noch mal - korrekter 
Code fürs Update ist ja da, abgesichert per Checksumme.

Frohes neues Jahr!

Max

von Frank K. (fchk)


Lesenswert?

Max G. schrieb:

> Das Update im RAM zu speichern ist nur dann sinnvoll, wenn du dir sicher
> bist, dass das Gerät auch nach einem gescheiterten Update wieder
> hochkommt und kommuniziert.

Hier nochmal eine Appnote zum Thema Dual-Bank Flash.
https://www.st.com/resource/en/application_note/an4767-onthefly-firmware-update-for-dual-bank-stm32-microcontrollers-stmicroelectronics.pdf

Ich denke, das bringt so sehr viel mehr an Betriebssicherheit, dass Du 
Dich damit beschäftigen solltest.

fchk

von Max G. (l0wside) Benutzerseite


Lesenswert?

OK, Dual-bank ist natürlich SEHR elegant. Flash kostet ja quasi nichts 
mehr.
Dann kann man die Daten nach dem Empfangen (fast) direkt ins Flash 
schreiben, das ist wesentlich schneller als KNX. Fast, weil natürlich 
blockweise im RAM gepuffert werden muss.

von Micha (michael_schwaer)


Lesenswert?

Max G. schrieb:
> Für ein Update sind Gruppenadressen in der KNX-Systematik der falsche
> Ansatz, dafür dient eigentlich MemoryWrite mit direkter Adressierung des
> Geräts. Technisch möglich ist es natürlich. Verwendest du den Weinzierl
> BAOS-IC, hast du einen Stack gekauft, oder hast du einen Freeware-Stack
> verwendet?

Ich verwende Weinzierl BAOS-IC bzw. BAOS-Modul, das am STM32 hängt. Gibt 
es damit eine Möglichkeit, per MemoryWrite eine eigene Firmware darüber 
zu übertragen?

Dir auch ein gutes neues Jahr!

Gruß
Micha

: Bearbeitet durch User
von Frank K. (fchk)


Lesenswert?

Micha schrieb:

> Ich verwende Weinzierl BAOS-IC bzw. BAOS-Modul, das am STM32 hängt. Gibt
> es damit eine Möglichkeit, per MemoryWrite eine eigene Firmware darüber
> zu übertragen?

Das sollte Weinzierl wissen. Und der wirds Dir auch sicher sagen, wenn 
Du ihm eine nette Mail schreibst.

fchk

von Max G. (l0wside) Benutzerseite


Lesenswert?

Hallo Micha,

dann wird es interessant. Verwendest du das BAOS-IC, um nachher ein 
zertifizierbares Gerät zu haben? Damit ist die Update-Möglichkeit nicht 
so recht verträglich. An der Stelle stand ich auch schon.
Rede mal mit den Weinzierl-Leuten, die die Zertifizierung machen (ich 
vermute mal, dass du das über die machen lässt, wenn du das BAOS-IC 
verwendest). Bis auf die Gefahr, dass man einen Schwall Niederbayrisch 
abbekommt, sind die eigentlich sehr nett :)

Zertifiziert wird ja die gesamte Applikation, also dein Code + der 
BAOS-IC. Wenn du nun deinen Code durch die Hintertür (und das ist der 
Ansatz mit der Gruppenadresse letzendlich) änderst, hast du keine 
zertifizierte Applikation mehr. Das könnte ein Problem sein.

Oder nutzt du das BAOS-IC nur, um dich nicht mit dem Stack rumschlagen 
zu müssen?

Grüße Max

von Micha (michael_schwaer)


Lesenswert?

Max G. schrieb:
> Oder nutzt du das BAOS-IC nur, um dich nicht mit dem Stack rumschlagen
> zu müssen?
>
> Grüße Max

Hallo Max,

ich brauche keine Zertifizierung. Wird nur für den Eigenbedarf 
verwendet.
Das BAOS-IC erleichtert einem die Realisierung von KNX-Geräten, ist aber 
trotzdem recht komplex.

Gruß
Micha

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.