Ein uC-Programm sollte vor dem Flashen, nach dem Flashen, nach einem Download zwecks Update und nach einem Reset mittels CRC überprüft werden (jedenfalls auf einem STM32, der CRC32 in Hardware kann). Dazu muss ein Programm auf dem PC das hex-File manipulieren. Alle beteiligten Programme müssen sich einig sein, auf welcher Adresse diese Prüfsumme steht. Aber nur das uC-Programm selbst kann die auf "natürliche" Art ansprechen. Eine feste Adresse für diverse kleine und große uC wäre nett. Das Ende des Flash ist zwar relativ fest, aber dann muss das Image immer die volle Größe haben. Am Ende des Programms ist mir viel zu kompliziert. Kurz hinter der Vektor Tabelle wäre ein guter Platz und in C leicht hinschreibbar. Große STM32 brauchen aber bis zu 2048 Byte für die Tabelle, dann liegt die Prüfsumme bei kleinen M0 mitten im nutzbaren Flash. Eine feste Adresse kommt nicht in Frage. Also muss das PC-Programm anhand der Daten im hex-File erkennen können, wo es die Prüfsumme hin schreiben soll. Dafür braucht man eine feste Adresse... Mein Plan: im ersten Wort der Vektor Tabelle steht der Stack Pointer. Ich lege den Stack immer an den Anfang des RAM und die Größe ist ja sowieso willkürlich. Also kann ich in den Bits 3 und 4 (evt. 5) vier (acht) verschiedene Plätze für die Prüfsumme kodieren. Als Feigling lasse ich Bit 0, 1 und 2 immer auf Null (der Stack ist im Betrieb 8-Byte aligned). Praktischerweise stehen diese Bits im allerersten Byte vom Image. Was könnte möglicherweise schief gehen?
Wozu benötigt der uC eine abgespeicherte Prüfsumme? Angenommen, dein uC stellte (z.B. beim booten) eine fehlerhafte Prüfsumme fest, was soll dann passieren? Wenn du sowieso den PC hast, um die Prüfsumme bei den o.g. Gelegenheiten zu verifizieren, dann reicht es ja, dass der uC die Prüfsumme berechnen und an den PC kommunizieren kann. Der PC kann die Prüfsumme anhand des HEX files ebenfalls errechnen, und prüfen ob beide CRCs identisch sind. Wenn nicht -> nochmal flashen/updaten etc.
:
Bearbeitet durch User
eagle user schrieb: > und nach einem Reset mittels CRC überprüft werden Das bedeutet, das möglicherweise defekte Programm muss sich selbst prüfen? Wie soll es das können, wenn es defekt ist?
Da das Image jeweils für einen bestimmten Prozessor ist, könnte sie auch an einer für den jeweiligen Prozessor günstigen Stelle liegen. Den beteiligten Programmen müßte man dann natürlich mitteilen für welchen Prozessor das Image ist. Zumal auch nicht festzustehen scheint, ob auf allen Systemen das gleiche Prüfverfahren zum Einsatz kommt. Ich habe auch schon gesehen, dass ein freier Eintrag in der Vectortable genutzt wird.
eagle user schrieb: > Eine feste Adresse für diverse kleine und große uC wäre nett. Mach das doch mit einem generischen Header, in dem Du per ifdefs die Adresse je nach Controller definierst. > Mein Plan: im ersten Wort der Vektor Tabelle steht der Stack Pointer. > Ich lege den Stack immer an den Anfang des RAM Da wrd ich nochmal drüber nachdenken, denn der Stack ist absteigend. Legst Du also den Stackpointer auf den Beginn des RAM, dann bekommst Du bei der ersten Nutzung des Stacks direkt einen Hardfault.
Rufus Τ. F. schrieb: > Wie soll es das können, wenn es defekt ist? Es ist theoretisch denkbar, daß es gerade so beschädigt ist, daß es trotzdem als OK hochläuft. Beispielsweise, indem die Bits so kippen, daß die Prüfroutine übersprungen wird. Das ist aber extrem unwahrscheinlich. Wenn Änderungen im Code sind, wird das wahrscheinlich einen Absturz geben. Dann merkt man, daß etwas verkehrt ist. Viel schlimmer ist es, wenn z.B. der Datenbereich beschädigt ist und das Programm zwar läuft, aber verkehrt. Diesen Fall erkennt man mittels Püfung der Firmware.
eagle user schrieb: > Das Ende > des Flash ist zwar relativ fest, aber dann muss das Image immer die > volle Größe haben. Nö, z.B. Intel-Hex kann auch Lücken haben. Man muß nur bei der CRC-Berechnung festlegen, daß Lücken dem gelöschten Flash (0xFF) entsprechen.
Joe F. schrieb: > Angenommen, dein uC stellte (z.B. beim booten) eine fehlerhafte > Prüfsumme fest, was soll dann passieren? Er sollte z.B. in einer Endlosschleife bleiben und auf jeden Fall nicht beginnen, die angeschlossene Anwendung zu steuern. Eine ausgefallene Steuerung erkennt man nämlich einfacher als eine fehlerhafte, zumal bei vernünftigem Systemdesign auch die Sicherheit profitiert.
Man könnte die Position ja "markieren". Sinngemäß etwa so:
1 | const struct checksum { |
2 | char marker[] = "/My/Check/sum/"; |
3 | uint32_t crc32sum = 0; |
4 | };
|
Dann kann man im .bin/.hex nach "/My/Check/sum/" suchen und unmittelbar darauf folgt die Checksum.
:
Bearbeitet durch User
Nop schrieb: > Joe F. schrieb: > >> Angenommen, dein uC stellte (z.B. beim booten) eine fehlerhafte >> Prüfsumme fest, was soll dann passieren? > > Er sollte z.B. in einer Endlosschleife bleiben (...) Könntest du die Beantwortung dieser Frage bitte dem TO überlassen?
Joe F. schrieb: > Könntest du die Beantwortung dieser Frage bitte dem TO überlassen? Das ist hier ein Forum und kein Zweiergespräch per PN oder Email.
Harry L. schrieb: > Dann kann man im .bin/.hex nach "/My/Check/sum/" suchen und unmittelbar > darauf folgt die Checksum. Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das Image verändert hat...
Nop schrieb: > Das ist hier ein Forum und kein Zweiergespräch per PN oder Email. Darum geht es nicht. Ich möchte nur gerne vom TO erfahren, was in dem Fall passieren soll anstatt wilder Spekulationen.
Joe F. schrieb: > Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins > Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das > Image verändert hat... JA, da war ich wohl ein wenig voreilig ;) War ein spontaner Gedanke....mea Culpa.
Joe F. schrieb: > Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins > Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das > Image verändert hat... Man kann die x Bytes der Prüfsumme auch beim Berechnen überspringen, wenn man rausbekommen hat, wo sie ist, und sie nur nach der Berechnung als erwarteten Wert heranziehen. Ob man sie dazu am Anfang, in der Mitte oder am Ende speichert, ist egal.
Nop schrieb: > Er sollte z.B. in einer Endlosschleife bleiben und auf jeden Fall nicht > beginnen, die angeschlossene Anwendung zu steuern. Wenn das Programm beschädigt ist, ist doch nicht nur das Erkennen einer solchen Beschädigung, sondern auch die Reaktion darauf undefiniert ("auf jeden Fall")?
Hannibal H. Hirnfurz schrieb: > Wenn das Programm beschädigt ist, ist doch nicht nur das Erkennen einer > solchen Beschädigung, sondern auch die Reaktion darauf undefiniert ("auf > jeden Fall")? Das ist die Theoretiker-Falle: wenn eine Lösung nicht 100.00% wasserdicht ist, dann ist es dasselbe wie wie eine 0%-Lösung.
Rufus Τ. F. schrieb: > eagle user schrieb: >> und nach einem Reset mittels CRC überprüft werden > > Das bedeutet, das möglicherweise defekte Programm muss sich selbst > prüfen? > > Wie soll es das können, wenn es defekt ist? Indem man die vorherige Version auf dem µC belässt und diese die Prüfung übernimmt. Erst wenn diese erfolgreich erfolgt ist wird der neu Bootloader gestartet damit er die andere Firmware startet, schlägt dies fehl bzw. kommt es zu Problemen setzt man wieder auf die alte Firmware. Natürlich muss man dann mehr Speicher im EEPROM einplanen als bei einfachen Lösungen die direkt überschreiben - aber gerade wenn man viele Systeme hat die über z.B. über Funk angebunden sind gilt safety first - mehrere Tausend Systeme neu zu flashen ist schlichtweg finanziell nicht rentabel. Ein µC mit >=2x so viel Speicher ist oftmals kein Problem.
Was ich noch ganz vergessen habe: Man muss unterschiedliche CRC Polynome benutzen bei den einzelnen Prüfungen. Ansonsten können Bitfehler trotz mehrmaliger Prüfung durchrutschen.
Rufus Τ. F. schrieb: > eagle user schrieb: >> und nach einem Reset mittels CRC überprüft werden > > Das bedeutet, das möglicherweise defekte Programm muss sich selbst > prüfen? > > Wie soll es das können, wenn es defekt ist? Es könnte z.B. auch sein, daß ein Bootloader die CRC prüft und im Falle eines Fehlers dann das defekte Hauptprogramm nicht startet, sondern nur im Bootloader-Modus auf ein neues, Prüfsumm-korrektes Programm wartet.
Nuger schrieb: > Was ich noch ganz vergessen habe: Man muss unterschiedliche CRC Polynome > benutzen bei den einzelnen Prüfungen. Ansonsten können Bitfehler trotz > mehrmaliger Prüfung durchrutschen. Desto komplexer der Prüfsummen-Algo, desto unwahrscheinlicher wird das. Wenn es nicht aufs letzte Byte oder die letzte µs ankommt nehme ich normal MD5 statt irgendeinem CRC32. Im Gegensatz zu CRC32 ist mir bei MD5 noch nie eine Kollision bei meinen Firmwares aufgetreten, auch wenn sie natürlich theoretisch möglich wäre.
Die Forderung von ganz oben ist nicht nur hypothetisch sondern sehr real: Nennt sich Sicherheitsnorm IEC 60335. http://www.all-electronics.de/hausgeraete-sicherer-machen/ Die Hersteller der gängigen Controller bieten meistens auch Libs und Samplecode für diesen Selbstcheck an. Da gehört der Flash auch dazu.
Der µC könnte beim ersten Start eine Prüfsumme erstellen und in irgendeinem nicht flüchtigen Speicher ablegen. Bei allen folgenden Starts kann er anhand der Prüfsumme ungewollte Veränderungen am Programm erkennen. Ich finde dieses Verfahren einfacher, als wenn die Prüfsumme von außen vorgegeben wird. Ein Schutz gegen Manipulation ist das aber nicht, denn das manipulierte Programm könnte natürlich auch einen manipulierten (oder gar unwirksamen) Prüfalgorithmus enthalten.
Stefan U. schrieb: > Der µC könnte beim ersten Start eine Prüfsumme erstellen und in > irgendeinem nicht flüchtigen Speicher ablegen. Bei allen folgenden > Starts kann er anhand der Prüfsumme ungewollte Veränderungen am Programm > erkennen. Das überzeugt mich nicht. Denn damit erkennst Du keinerlei Übertragungsfehler auf den µC. Einmal die JTAG-Pins nicht richtig aufgesetzt, der Testpunkt etwas oxidiert etc. und schon wackelt einmal ein Bit. Das dürfte erfahrungsgemäß viel öfters auftreten, als daß bei einem ursprünglich korrekt geflashtem µC nach einigen Jahren mal ein Bit kippt.
Wenn du eine Prüfsumme an eine variable Adresse im Programmspeicher ablegen willst, kannst du eine eindeutige Markierung davor stellen. Zum Beispiel "CodeChkSum:xxxx". Eine so markierte Stelle kann man leicht finden. Du musst dann natürlich sicherstellen, dass der String nicht auch noch woanders vor kommt.
Stefan U. schrieb: > Der µC könnte beim ersten Start eine Prüfsumme erstellen und in > irgendeinem nicht flüchtigen Speicher ablegen. Bei allen folgenden > Starts kann er anhand der Prüfsumme ungewollte Veränderungen am Programm > erkennen. Das würde ich nicht so umsetzen. Eine permanent defekte Speicherzelle würde damit nicht auffallen und das Programm zeigt dennoch Fehlverhalten. Gerd E. schrieb: > Es könnte z.B. auch sein, daß ein Bootloader die CRC prüft und im Falle > eines Fehlers dann das defekte Hauptprogramm nicht startet, sondern nur > im Bootloader-Modus auf ein neues, Prüfsumm-korrektes Programm wartet. So kenne ich das auch. Oftmals sogar mit zwei Images, falls es der Speicherplatz zulässt. Dann darf auch beim Update was schieflaufen und die Kiste startet dennoch. Ich entscheide mich lieber dafür, NICHTS zu tun, als ein Programm auszuführen dass dann unter Umständen IRGENDWAS macht. Allein schon von der Zuverlässigkeit und Sicherheit her ist sowas zwingend notwendig in vielen Anwendungen. Und wie der Loader die Prüfsumme findet: Man sagt es ihm. Beim STM32 würde ichs so lösen: - Der Loader hat hardcoded das Ende des Flashs drinstehen. Das ist spätestens beim Linken bekannt, da im Linkerskript die Speicherbereiche drinstehen. Linker-Konstanten kann man in C verwenden, so kommt die Info in den Loader. - Am Ende des Flashs steht ein Struct. Dieses Struct enthält: * Startadresse des Images (ggf. optional) * Größe des Images (Größe = 0 => kein Image vorhanden) * Prüfsumme des Images - Fertig. Ob dazwischen (also zwischen Image und Flashende) "Löcher" sind ist egal. Die Struktur am Ende des Flashs wird nicht explizit ins Image geschrieben sondern beim Update bzw. bei der Fertigung erstellt. Ach ja: Beim Update wird auch die Prüfsumme übertragen und mit den empfangenen Daten verglichen. So ähnlich habe ich das bereits mal umgesetzt.
:
Bearbeitet durch User
Gerd E. schrieb: > Denn damit erkennst Du keinerlei Übertragungsfehler auf den µC. Einmal > die JTAG-Pins nicht richtig aufgesetzt, der Testpunkt etwas oxidiert > etc. und schon wackelt einmal ein Bit. Das dürfte erfahrungsgemäß viel > öfters auftreten, als daß bei einem ursprünglich korrekt geflashtem µC > nach einigen Jahren mal ein Bit kippt. Wenn Du den Flash-Inhalt über JTAG schreibst, kannst Du ihn auch über JTAG validieren.
Joe F. schrieb: > Wozu benötigt der uC eine abgespeicherte Prüfsumme? z.B. um bei einem Update das neue Image vorher und nach dem Flashen zu testen. Ich finde, eine vom Image getrennte Prüfsumme ist noch umständlicher. Die Prüfsumme ist auch nur ein Wort in einem Header mit Name, Version, Zeitstempel, Seriennr. und einer Angabe, zu welcher Hardware das Programm gehört. > Angenommen, dein uC stellte (z.B. beim booten) eine fehlerhafte > Prüfsumme fest, was soll dann passieren? Rufus Τ. F. schrieb: > eagle user schrieb: >> und nach einem Reset mittels CRC überprüft werden > > Das bedeutet, das möglicherweise defekte Programm muss sich selbst > prüfen? Ein kleiner Teil des Programms muss sich selbst prüfen. Wenn das nicht klappt: Endlosschleife + Watchdog. Normal wird anschließend das eigentliche Programm geprüft. Bis dahin wird fast keine Hardware initialisiert. Wenn das Programm groß genug ist, ist es nochmal unterteilt. Die Teile werden getrennt geprüft und sind in gewissen Grenzen getrennt lauffähig. Steffen R. schrieb: > Da das Image jeweils für einen bestimmten Prozessor ist, könnte > sie auch > an einer für den jeweiligen Prozessor günstigen Stelle liegen. > > Den beteiligten Programmen müßte man dann natürlich mitteilen für > welchen Prozessor das Image ist. Genau das ist mein Problem :) > Zumal auch nicht festzustehen scheint, ob auf allen Systemen > das gleiche Prüfverfahren zum Einsatz kommt. Doch, das ist der Plan. > Ich habe auch schon gesehen, dass ein freier Eintrag in der Vectortable > genutzt wird. So war es bis gestern und jetzt fürchte ich mich, dass genau der Eintrag beim nächsten Chip nicht mehr frei ist. Den Stack-Pointer-Eintrag wird man wohl eher nicht ändern. Nop schrieb: > eagle user schrieb: >> Mein Plan: im ersten Wort der Vektor Tabelle steht der Stack Pointer. >> Ich lege den Stack immer an den Anfang des RAM > > Da wrd ich nochmal drüber nachdenken, denn der Stack ist absteigend. > Legst Du also den Stackpointer auf den Beginn des RAM, dann bekommst Du > bei der ersten Nutzung des Stacks direkt einen Hardfault. Ach menno, den Stack, nicht den Stackpointer. Den Hardfault gibt's dann, wenn der Stack überläuft. Und das ist so dermaßen angenehm, ich weiß garnicht, wie man früher ohne ausgekommen ist. Harry L. schrieb: > Joe F. schrieb: >> Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins >> Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das >> Image verändert hat... > > JA, da war ich wohl ein wenig voreilig ;) > > War ein spontaner Gedanke....mea Culpa. Das ist doch das kleinste Problem, die spontanen Gedanken sind hinterher oft die besten. Nuger schrieb: > Was ich noch ganz vergessen habe: Man muss unterschiedliche CRC > Polynome > benutzen bei den einzelnen Prüfungen. Ansonsten können Bitfehler trotz > mehrmaliger Prüfung durchrutschen. Naja, dann müsste man aber auch jeden einzelnen Maschinenbefehl prüfen. Soviel Sicherheit brauche ich zum Glück nicht. Stefan U. schrieb: > Ein Schutz gegen Manipulation ist das aber nicht, denn das manipulierte > Programm könnte natürlich auch einen manipulierten (oder gar > unwirksamen) Prüfalgorithmus enthalten. Ich glaube, das war schon geklärt, dass ein Schutz gegen Manipulation mit normalen uC garnicht möglich ist. Johannes O. schrieb: > Und wie der Loader die Prüfsumme findet: Man sagt es ihm. Beim STM32 > würde ichs so lösen: > - Der Loader hat hardcoded das Ende des Flashs drinstehen. Das ist > spätestens beim Linken bekannt, da im Linkerskript die Speicherbereiche > drinstehen. Linker-Konstanten kann man in C verwenden, so kommt die Info > in den Loader. OK, aber das gilt nicht für die PC-Programme. Die müssen die Metadaten im Hex-File "finden". Und gerade die sollen ja universell sein.
Joe F. schrieb: > > Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins > Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das > Image verändert hat... Dann ist es ja ganz einfach (sofern man xor verwendet) definiert man einfach, dass alle bytes des Flashes in der XOR Summe 0 ergeben müssen. Bei CRC32 musss man halt so lange Bits kippen, bis 0 raus kommt. Bei komplexeren Algorithmen wie MD5/SHA... hat mam aber schlechte Karten VG Roland
eagle user schrieb: > Ein uC-Programm sollte vor dem Flashen, nach dem Flashen, nach einem > Download zwecks Update und nach einem Reset mittels CRC überprüft werden > (jedenfalls auf einem STM32, der CRC32 in Hardware kann). Dazu muss ein > Programm auf dem PC das hex-File manipulieren. Alle beteiligten > Programme müssen sich einig sein, auf welcher Adresse diese Prüfsumme > steht. Aber nur das uC-Programm selbst kann die auf "natürliche" Art > ansprechen. Was genau heist vor und nach dem flashen? wie wird geflasht? JTAG? Im Flash abgelegter Bootloader? Wenn Bootloader, der wird ja wohl wissen, wo die Vectortabelle des jeweiligen Chips aufhört. Wenn JTAG, wozu brauchts da eine Checksumme, ich kann nach dem Flashen per JTAG ja wohl Problemlos eine Verifikation mit der Originaldatei anstellen Was bedeutet Download? Wir da ein extra Stück Code gestartet? Die Firmware kann sich ja nicht selbst überschreiben. Nach dem Reset die CRC von sich selbst zu berechnen ist simpel. Ein bischen mehr Details zu den Anwendungsfällen wären schon nett. > volle Größe haben. Am Ende des Programms ist mir viel zu kompliziert. Drei Zeilen im Linkerscript? > Kurz hinter der Vektor Tabelle wäre ein guter Platz und in C leicht > hinschreibbar. Große STM32 brauchen aber bis zu 2048 Byte für die > Tabelle, dann liegt die Prüfsumme bei kleinen M0 mitten im nutzbaren > Flash. > > Eine feste Adresse kommt nicht in Frage. Also muss das PC-Programm > anhand der Daten im hex-File erkennen können, wo es die Prüfsumme hin > schreiben soll. Dafür braucht man eine feste Adresse... An das Ende der Firmware? Ansonsten nutzt man für sowas normalerweise eine Info Struktur irgendwo in der Firmware. Da kann man auch noch mehr Informationen hinterlegen. z.B. für den Bootloader, falls es einen gibt. > > Mein Plan: im ersten Wort der Vektor Tabelle steht der Stack Pointer. > Ich lege den Stack immer an den Anfang des RAM und die Größe ist ja > sowieso willkürlich. Also kann ich in den Bits 3 und 4 (evt. 5) vier > (acht) verschiedene Plätze für die Prüfsumme kodieren. Als Feigling > lasse ich Bit 0, 1 und 2 immer auf Null (der Stack ist im Betrieb 8-Byte > aligned). Praktischerweise stehen diese Bits im allerersten Byte vom > Image. Viel zu kompliziert und keiner verstehts. Dann besser ein Cookie in der Firmware was die Software Suchen kann. Die Firmware auf dem Mikrocontroller weis eh wo alles steht.
>> Der µC könnte beim ersten Start eine Prüfsumme erstellen und in >> irgendeinem nicht flüchtigen Speicher ablegen. > Eine permanent defekte Speicherzelle würde damit nicht auffallen > und das Programm zeigt dennoch Fehlverhalten. > Das überzeugt mich nicht. > Denn damit erkennst Du keinerlei Übertragungsfehler auf den µC. Eine permanent defekte Zelle sowie Übertragungsfehler würden schon während des Flashens auffallen, denn natürlich verifiziert man danach nochmal. Es ging doch darum, festzustellen, ob das Programm später im Betrieb (unabsichtlich) kaputt gegangen ist. Die von mir empfohlene Methode wurde in den 90er Jahren von eine Zeit lang von vielen Virenscannern verwendet, bis man sich bewusst wurde, dass das nicht gegen gezielte Manipulation hilft.
eagle user schrieb: > Nuger schrieb: >> Was ich noch ganz vergessen habe: Man muss unterschiedliche CRC >> Polynome >> benutzen bei den einzelnen Prüfungen. Ansonsten können Bitfehler trotz >> mehrmaliger Prüfung durchrutschen. > Naja, dann müsste man aber auch jeden einzelnen Maschinenbefehl prüfen. > Soviel Sicherheit brauche ich zum Glück nicht. Kostet nichts und schadet nicht. Wenn du durch einen derart absurden Fehler 1000 Geräte von Hand flashen musst sind das leichtsam >2000€ an Kosten, da stelle ich lieber sicher dass so ein Fehler von vornherein nicht passieren kann. Gerade wenn die Tags fest verbaut sind wird das erst richtig lustig, da tanzt dein Kunde dann.
Roland P. schrieb: > Joe F. schrieb: >> >> Das Problem einer Checksumme im Image ist, sobald man die Checksumme ins >> Image schreibt, stimmt die Checksumme nicht mehr, da die Checksumme das >> Image verändert hat... > > Dann ist es ja ganz einfach (sofern man xor verwendet) definiert man > einfach, dass alle bytes des Flashes in der XOR Summe 0 ergeben müssen. > > Bei CRC32 musss man halt so lange Bits kippen, bis 0 raus kommt. Bei > komplexeren Algorithmen wie MD5/SHA... hat mam aber schlechte Karten viel einfacher: man verwendet die CRC-Hardware des STM32 und überspringt bei der Berechnung das eine CRC-Wort, auch wenn es mitten drin steht. Andreas M. schrieb: > Was genau heist vor und nach dem flashen? wie wird geflasht? JTAG? Im > Flash abgelegter Bootloader? Z.B. lädt ein Bootloader von irgendwo her ein Update ins RAM. Das muss auf jeden Fall geprüft werden. Dann flasht er und prüft das Ergebnis. Später prüft er nach einem Reset das Anwendungsprogramm und startet es oder wartet auf ein Update. > Wenn Bootloader, der wird ja wohl wissen, wo die Vectortabelle des > jeweiligen Chips aufhört. Wenn JTAG, wozu brauchts da eine Checksumme, > ich kann nach dem Flashen per JTAG ja wohl Problemlos eine > Verifikation mit der Originaldatei anstellen Beim ersten Mal wird mit dem eingebauten UART-Bootloader geflasht. Damit dauert ein Verify ziemlich lange, der uC selbst kann das viel schneller. > Was bedeutet Download? Wir da ein extra Stück Code gestartet? Die > Firmware kann sich ja nicht selbst überschreiben. Das Anwendungsprogramm geht auf Standby, lädt das neue Image vom USB-Stick oder aus dem Internet ins RAM und startet einen Flashloader, Der prüft das Image und überschreibt das Anwendungsprogramm. Wenn der uC kein Dual Bank Flash hat, kopiert er sich vorher ins RAM. > > Nach dem Reset die CRC von sich selbst zu berechnen ist simpel. > > Ein bischen mehr Details zu den Anwendungsfällen wären schon nett. Eigentlich möchte ich eine möglichst universelle Lösung, besonders, was die Programme auf dem PC angeht. Die sollen mindestens mit STM32L030 bis STM32L476 funktionieren. Zusätzlich soll ein Update über möglichst viele Wege möglich sein. >> volle Größe haben. Am Ende des Programms ist mir viel zu kompliziert. > > Drei Zeilen im Linkerscript? vielleicht, aber am Anfang kann es nicht komplizierter sein. > Ansonsten nutzt man für sowas normalerweise > eine Info Struktur irgendwo in der Firmware. Da kann man auch noch mehr > Informationen hinterlegen. z.B. für den Bootloader, falls es einen gibt. ... und Infos im Klartext für Menschen, die einen hexdump machen. Genau so wird es gemacht. Diese Info Struktur hat hier ca. 80 Byte. Die Frage ist nur, wie findet man die? Externe Programme haben eben nur die hex-Datei und müssen erstmal diese Info lesen, bevor sie wissen, zu welchem Chip die Datei gehört und wo die Info steht... > Viel zu kompliziert und keiner verstehts. Das bin ich gewohnt ;) > Dann besser ein Cookie in der Firmware was die Software Suchen kann. > Die Firmware auf dem Mikrocontroller weis eh wo alles steht. OK, überredet. "Suchen" heißt ja nicht Byte für Byte, es kommen ja nur wenige Adressen in Frage. Man braucht nicht einmal ein extra Cookie, die Struktur der Info ist ja konstant und bekannt. Und mit den Info-Daten sind jede Menge Plausibilitätschecks möglich, das sollte reichen.
Hi, ich habe mir dazu auch schonmal Gedanken gemacht. Ich würde ein Info-Struct nach der Vectortabelle platzieren. Wenn man es davor platziert geht evtl. eine ganze Flash Page dafür drauf, da die Tabelle je nach Controller ein bestimmtes Alignment braucht. Am Ende des Flash geht auch eine ganze Page drauf. Hat jemand eine Idee, wie man das Verfahren kombinieren kann mit einer EEPROM Emulation im Flash bzw. mit sich zur Laufzeit ändernden Daten? Diese würde ich gerne in eine eigene Section legen hinter der Applikation. Sie sollten nicht zusammen mit der Applikation vor dem Start geprüft werden, da sie sich ja ändern können. (Fürs Prüfen der Daten ist dann die Applikation verantwortlich) D.h. irgendwie muss man die Länge der Firmware ohne die Daten Section ermitteln. Dazu eine Idee? Lg Chris
Chris schrieb: > Hi, > > ich habe mir dazu auch schonmal Gedanken gemacht. Ich würde ein > Info-Struct nach der Vectortabelle platzieren. Wenn man es davor > platziert geht evtl. eine ganze Flash Page dafür drauf, da die Tabelle > je nach Controller ein bestimmtes Alignment braucht. Außerdem funktioniert es nicht, weil mindestens der Reset Vector auf 0x4 gebraucht wird. Na gut, der könnte auch am Anfang der Info-Struct stehen. Direkt hinter der Vector Table scheint mir der natürlichste Platz zu sein. > Am Ende des Flash geht auch eine ganze Page drauf. nicht unbedingt, aber man muss sich sehr gut im Linker Script auskennen. > Hat jemand eine Idee, wie man das Verfahren kombinieren kann mit einer > EEPROM Emulation im Flash bzw. mit sich zur Laufzeit ändernden Daten? > Diese würde ich gerne in eine eigene Section legen hinter der > Applikation. > D.h. irgendwie muss man die Länge der Firmware ohne die Daten Section > ermitteln. Mal angenommen, man braucht kein C++ und mal angenommen, man kommt mit dieser Flash-Belegung aus, mit dem EEPROM auf den höchsten Adressen: * vector table mit info struct * text (das eigentliche Programm) * (anonymer Bereich mit Daten zur RAM-Initialisierung) * (eine Lücke bis zum nächsten Flash Sektor) * EEPROM Emulation Für das EEPROM braucht man im Linker Script eine eigene section. Damit die auf einer bestimmten Adresse landet, braucht man einen Eintrag im Abschnitt memory{}. Wenn man am Ende der text section ein Symbol definiert, hat man die erste Adresse der Init-Daten. Jetzt muss man nur noch die Größe des Datenbereichs addieren und bekommt die erste Adresse, die nicht mehr geprüft werden muss (wenn man bei 0x08000000 anfängt). Wahrscheinlich gibt es dieses Symbol schon, weil es von der crt0 gebraucht wird, ebenso wie die Anzahl der Datenbytes. Adresse plus Datenbytes kann man statisch in die init struct eintragen, dann weiß jeder, wieviel geprüft werden muss.
eagle user schrieb: > OK, aber das gilt nicht für die PC-Programme. Die müssen die Metadaten > im Hex-File "finden". Und gerade die sollen ja universell sein. Speziell bei solchen universellen Lösungen kommt ein weiteres Problem hinzu. Man muss absichern, dass das Image auch wirklich für das jeweilige Gerät ist. Ich spreche das nur an, weil ja genau an dem Merkmal, welches die Geräte zur Validierung nutzen auch die PC Programme das Image erkennen können.
eagle user schrieb: >> Was bedeutet Download? Wir da ein extra Stück Code gestartet? Die >> Firmware kann sich ja nicht selbst überschreiben. > Das Anwendungsprogramm geht auf Standby, lädt das neue Image vom > USB-Stick oder aus dem Internet ins RAM und startet einen Flashloader, > Der prüft das Image und überschreibt das Anwendungsprogramm. Wenn der uC > kein Dual Bank Flash hat, kopiert er sich vorher ins RAM. Die Programme haben maximal RAM Größe? Häufig ist der Flash doch um einiges größer. eagle user schrieb: >> Ansonsten nutzt man für sowas normalerweise >> eine Info Struktur irgendwo in der Firmware. Da kann man auch noch mehr >> Informationen hinterlegen. z.B. für den Bootloader, falls es einen gibt. > ... und Infos im Klartext für Menschen, die einen hexdump machen. Genau > so wird es gemacht. Diese Info Struktur hat hier ca. 80 Byte. Die Frage > ist nur, wie findet man die? Externe Programme haben eben nur die > hex-Datei und müssen erstmal diese Info lesen, bevor sie wissen, zu > welchem Chip die Datei gehört und wo die Info steht... Wie findet ihr die bisher? Im Hexdump können es auch deine Kollegen nicht sehen. Im Allgemeinen sind die Klartextinformationen im Binärfile. Da du die Programme für deine Spezial-Allgemeinlösung eh selbst programmieren oder anpassen mußt ist mir unklar, warum du nicht den einfacheren Weg gehst und passende Optionen einfügst. "passend" heißt hier nicht unbedingt Prozessor, könnte auch die Adresse sein. Dann brauchst du die Programme nicht mit jedem weiteren Gerät neu anzufassen. Und vielleicht wird's ja auch mal eine andere Prozessorfamilie?
Steffen R. schrieb: > eagle user schrieb: >>> Was bedeutet Download? Wir da ein extra Stück Code gestartet? Die >>> Firmware kann sich ja nicht selbst überschreiben. >> Das Anwendungsprogramm geht auf Standby, lädt das neue Image vom >> USB-Stick oder aus dem Internet ins RAM und startet einen Flashloader, >> Der prüft das Image und überschreibt das Anwendungsprogramm. Wenn der uC >> kein Dual Bank Flash hat, kopiert er sich vorher ins RAM. > > Die Programme haben maximal RAM Größe? Häufig ist der Flash doch um > einiges größer? Der STM32F205 hat z.B. 128KB RAM und 128KB Flash-Sektoren. Die komplette Anwendung ist sowieso in ca. 6 Teile ("Programme") unterteilt. Da funktioniert das auf ganz natürlich Art und Weise. Neuere Chips haben kleinere Flash-Segmente und mindestens 64 + 16KB RAM, da darf ein Programm-Teil eben nur 64KB groß sein. Und: je kleiner, umso besser funktioniert ein CRC. > eagle user schrieb: >>> Ansonsten nutzt man für sowas normalerweise >>> eine Info Struktur irgendwo in der Firmware. Da kann man auch noch mehr >>> Informationen hinterlegen. z.B. für den Bootloader, falls es einen gibt. >> ... und Infos im Klartext für Menschen, die einen hexdump machen. Genau >> so wird es gemacht. Diese Info Struktur hat hier ca. 80 Byte. Die Frage >> ist nur, wie findet man die? Externe Programme haben eben nur die >> hex-Datei und müssen erstmal diese Info lesen, bevor sie wissen, zu >> welchem Chip die Datei gehört und wo die Info steht... > > Wie findet ihr die bisher? > Im Hexdump können es auch deine Kollegen nicht sehen. > Im Allgemeinen sind die Klartextinformationen im Binärfile. Sind sie auch, mit (sinngemäß) "hexdump -C programm.elf" konnten/können Menschen das finden. Programmen musste man es extra per Kommandozeile/Mausclick sagen. Ich finde es schöner, wenn alles in einer Datei steht. Evt. behält man den Mausclick bei und das Programm vergleicht den Wunsch mit der Wirklichkeit in der Datei und im Chip. > Da du die Programme für deine Spezial-Allgemeinlösung eh selbst > programmieren oder anpassen mußt ist mir unklar, warum du nicht den > einfacheren Weg gehst und passende Optionen einfügst. > "passend" heißt hier nicht unbedingt Prozessor, könnte auch die Adresse > sein. Dann brauchst du die Programme nicht mit jedem weiteren Gerät neu > anzufassen. Brauche ich auch nicht. Erstmal stehen alle benötigten Adressen in der Datei und zusätzlich das, was man beim STM32 als Product ID auslesen kann. Diese Daten kommen aus einer "imageheader.c". > Und vielleicht wird's ja auch mal eine andere Prozessorfamilie? Dann ändert sich ja auf jeden Fall die Flash-Methode, evt. muss ich der Hardware sogar einen JTAG-Stecker spendieren, dann kommt es auf solche Kleinigkeiten auch nicht mehr an...
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.