Hallo Zusammen
Folgendes Szenario:
Ich habe auf einem STM32F100 (mit 128kB Flash) einen Bootloader und eine
Firmware. Bootloader ab 0x08000000, FW ab 0x08004000, Log-Daten ab
0x08014000 bis zum Flashende. Compiliert und Entwickelt wird mit Keil.
Ich möchte nun via Bootloader die Log-Daten an einen PC senden. Dazu
hätte ich gerne die FW-Version mit welcher die Log-Daten aufgezeichnet
wurden.
Wie macht Ihr das bei euren Projekten mit Bootloader?
- eine Konstante mit fixer Adresse in der FW, damit der Bootloader diese
einfach auslesen/finden kann?
- eine Flashpage reservieren für die Versionsinformation?
- die Checksumme über den FW-Bereich als Versionsinformation?
- Konstruckt aus MagicNumber und Version, welches im FW-Bereich gefunden
werden kann?
- Andere Vorschläge?
Die Version mit der Konstanten sah am Anfang verlockend aus, allerdings
funktioniert sie nur mit Hindernissen (eigens Linker-Skript). Ich habe
die Konstante ans Ende des FW-Flashbereichs legen wollen, da hat mir
aber der Kompiler noch Initialisierungs-Code dahinter geschoben und
somit in den Log-Daten Bereich. Also müsste ich via Linker-Skript eine
Section für die Konstante am Ende hinzufügen. Unschön ...
Was haltet Ihr für den besten Weg?
Gruess Claudio
Die Firmware ist mit einem Descriptor versehen, der beim Update (via
Bootloader) von diesem in eine separate Flash-Page übertragen wird, die
auch Prüfsummen, Einsprungadresse usw. enthält.
Bei mir wird die Versionsnummer vom Subversion erzeugt und direkt als
Konstante einkompiliert, lässt sich dann auch manuell vom Nutzer im
Infoscreen abfragen.
Ich würde sie einfach direkt in den Quelltext schreiben.
Sobald eine Änderung den ersten groben Test überstanden hat, wird die
Nummer aktualisiert, bevor man den Code bzw die Firmware weiter gibt.
x^2 schrieb:> Die Firmware ist mit einem Descriptor versehen, der beim Update (via> Bootloader) von diesem in eine separate Flash-Page übertragen wird, die> auch Prüfsummen, Einsprungadresse usw. enthält.
Ok, universell, braucht aber separate Flash Page. Gut.
Walter T. schrieb:> Bei mir wird die Versionsnummer vom Subversion erzeugt und direkt als> Konstante einkompiliert, lässt sich dann auch manuell vom Nutzer im> Infoscreen abfragen.
Das beantwortet leider meine Fragen nach wie es in der FW abgelegt wird
nicht. Wir machen das aber mit der Versionsvergabe auch so.
x^2 schrieb:> Die Firmware ist mit einem Descriptor versehen, der beim Update (via> Bootloader) von diesem in eine separate Flash-Page übertragen wird, die> auch Prüfsummen, Einsprungadresse usw. enthält.
wie bildest du den Descriptor in der FW ab, so dass der Bootlader diesen
aus der FW extrahieren kann? oder wird der sepparat an den Bootloader
übermittelt?
Claudio F. schrieb:> wie es in der FW abgelegt wird
Ich verstehe die Frage nicht. Die Versionsnummer liegt wie alle anderen
String Literals irgendwo in der data section, so wie alle anderen
Lookup-Tabellen, Bitmaps etc. auch.
Claudio F. schrieb:> Ok, universell, braucht aber separate Flash Page. Gut.
Braucht man sowieso: Checkt dein Bootloader gar nicht die Prüfsumme(n)
der Firmware? Wo ist diese gespeichert? Was ist mit Einsprungadresse,
Basisaddresse der Interrupt-Vektortabelle? Wenn das alles fix verdrahtet
an Adresse XY in der Firmware steht oder als bekannt vorausgesetzt wird,
kann man dieses Prinzip natürlich auch für die Versionsinfo übernehmen.
[Prüfsummen (Mehrzahl) da die Firmware durchaus segmentiert sein kann,
also über größere Lücken im Adressraum verteilt ist. Ein Spezialfall,
aber bei mir tatsächlich der Fall.]
Claudio F. schrieb:> wie bildest du den Descriptor in der FW ab, so dass der Bootlader diesen> aus der FW extrahieren kann? oder wird der sepparat an den Bootloader> übermittelt?
Der Descriptor existiert unabhängig von der Firmware (=Binärcode). Er
wird in das Format eingebracht, das beim Firmware-Update an den
Bootloader übertragen wird. Der Bootloader extrahiert daraus den
Descriptor und speichert ihn.
Walter T. schrieb:> Claudio F. schrieb:>> wie es in der FW abgelegt wird>> Ich verstehe die Frage nicht. Die Versionsnummer liegt wie alle anderen> String Literals irgendwo in der data section, so wie alle anderen> Lookup-Tabellen, Bitmaps etc. auch.
Wie findet der Bootloader dann dieses String-Literal? Dieses kann ja vom
Linker irgendwo plaziert werden. Deshalb die Frage wie man das am besten
macht ... und nein, der Bootloader kennt keine Funktionen der FW, also
getVersion() hätte das gleiche Problem wie eine Konstante ...
Ah, Kaffee ist eine magische Flüssigkeit. Ich habe die Frage
nachträglich dann doch verstanden, nachdem sie gemütlich in die Tasse
träufelte.
Ich habe mich damals entschieden, dass der Bootloader die
Firmware-Version nicht kennen muss. Der soll gefälligst einfach alles
draufschieben, was er soll.
...
Wie wäre es mit einer ungenutzten ISR? Die Speicheradressen stehen
bombenfest. Dann wenn die Get-Funktion eine ISR ist, dürfte das
innerhalb der Prozessor-Familie sehr portabel sin.
Walter T. schrieb:> Ah, Kaffee ist eine magische Flüssigkeit. Ich habe die Frage> nachträglich dann doch verstanden, nachdem sie gemütlich in die Tasse> träufelte.>> Ich habe mich damals entschieden, dass der Bootloader die> Firmware-Version nicht kennen muss. Der soll gefälligst einfach alles> draufschieben, was er soll.>> ...>> Wie wäre es mit einer ungenutzten ISR? Die Speicheradressen stehen> bombenfest. Dann wenn die Get-Funktion eine ISR ist, dürfte das> innerhalb der Prozessor-Familie sehr portabel sin.
Jaa Kaffee, gutes Stichwort :-)
hm, guter Gedanke mit den ISR-Adressen ... muss ich wohl auch bei einer
Tasse darüber nachdenken ...
Danke für die Inputs, auch an x^2
Bei dem Projekt an dem ich aktuell arbeite legt die Firmware ein
Versions-Struct vor den Resetvektor an eine konstante Adresse. Ich
versteh nicht ganz wo da ein Problem sein soll? Durch den Bootloader
muss man das Linkerskript ohnehin anpassen?
Claudio F. schrieb:> Ich möchte nun via Bootloader die Log-Daten an einen PC senden. Dazu> hätte ich gerne die FW-Version mit welcher die Log-Daten aufgezeichnet> wurden.>> Wie macht Ihr das bei euren Projekten
Ich hab das im Makefile:
1
# generate a version.h header file with defines
2
# for build time and git revision.
3
src/version.h: force
4
echo "/* Generated by Makefile. Exclude this header from version control! */\n" > src/version.h
Was ist das eigentliche Problem? Wenn es die feste Adresse für die
Konstante ist:
<konstante> __attribute__((at(.....)));
Wenn ich mich recht erinnere dürfen die Bereiche nicht im Scatterfile
enthalten sein. Muss man aus der Speicherdefinition rausnehmen.
Vincent H. schrieb:> Bei dem Projekt an dem ich aktuell arbeite legt die Firmware ein> Versions-Struct vor den Resetvektor an eine konstante Adresse. Ich> versteh nicht ganz wo da ein Problem sein soll? Durch den Bootloader> muss man das Linkerskript ohnehin anpassen?
Auch ein Gedanke dem ich noch nicht hatte, die Vectortabelle ein wenig
nach hinten schieben und die Versionsinfo davor plazieren. Geht in Keil
dann auch ohne Linker-Script (nur IDE Einstellungen und VECT_TAB_OFFSET
im Code ...
Danke für den Tipp
Man kann sich ja direkt hinter der Vektortabelle noch eine section
anlegen, die liegt dann immer am selben offset und da stört sie auch
niemanden und nimmt nicht mehr Platz weg als notwendig.
Man kann auch seinen Startup-Code so umbauen daß er das direkt hinter
die Vektoren schreibt, dann hat man es auch an bekannten festen Offset
und braucht überhaupt keine zusätzliche Section.
Bernd K. schrieb:> Claudio F. schrieb:>> Ich möchte nun via Bootloader die Log-Daten an einen PC senden. Dazu>> hätte ich gerne die FW-Version mit welcher die Log-Daten aufgezeichnet>> wurden.>>>> Wie macht Ihr das bei euren Projekten>> Ich hab das im Makefile:
fehlt noch ein:
1
.PHONY: force
Das war weiter oben, habs nicht mitkopiert. Sorry.
So, hab mich für eine Variante entschieden die auf einem STM32F100 mit
Keil Sinn macht und funktioniert:
Die Vektrotabelle muss ja immer an einer geraden Adresse (1kB
Blockgrenze) stehen. Sieht der STM32 oder CM3 so vor ...
Deshalb hab ich meine Versionsvariabel direkt hinter die Vectortabelle
gestellt. Da die Tabelle eine fixe Grösse hat (je na Derivat
unterschiedlich), ist die Position der Versionsinformation bekannt. Das
Ganze dann im Scatterfile entsprechend definiert und Voila, Der
Bootloader kann seine eigene Verison und die Version der FW lesen. Ok,
die eigene Version ist auch anders zu lösen, funktioniert aber genau so
gut ...
Zur Komplettierung hier noch ein Scatterfile von Keil als Beispiel: