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.
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.
Und immer an Murphy denken: genau dann wenn du updatest fällt der Strom aus
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.
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
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.
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
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
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
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.
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.