Hallo,
wie schon im Betreff geschrieben habe ich eine Frage zum Verständniss
über die Speicherverwaltung von Variablen.
In meinem kleinen Programm habe ich auch SD-Kartenzugriff mit Fat und
diesen möchte ich gleichzietig auch als Bootloader mit nutzen. Also will
ich diesen Teil an einer bestimmten Stelle im Speicher ablegen, sodass
es beim flashen nicht überschrieben werden kann. Da ich den Programmteil
aber auch in meinem normalen Programmablauf nutzen möchte muss ich ja
auf die selben Variablen zugreifen können. Ist dieses prinzipiell
möglich oder habe ich einen falschen Ansatz gewählt.
Ich weiß nicht, ob Du Dich in der Bezeichnung geirrt hast... aber
Variablen liegen normalerweise im RAM und nicht im Flash, da sie ja wie
der Name schon sagt variabel sein sollen. Wenn Du sie ins Flash legst,
sind's Konstanten.
Wenn Du allerdings z.B. einige Programmteile (Bootloader, ...) im Flash
ablegen willst und dieser Bereich nicht vom "normalen" Programm benutzt
werden soll, kannst Du im Linker File verschiedene Bereiche definieren.
Beim IAR sähe das etwa so aus:
1
vorher:
2
-Z(CODE)CODE=1100-FFDF
3
4
nachher:
5
-Z(CODE)CODE=2000-FFDF// "normaler" Programmcode
6
-Z(CODE)MEIN_BEREICH=1100-1FFF// Bereich für Bootloader oder so...
Deine Bootloader-Funktion musst Du dann im Sourcecode explizit in den
Bereich "MEIN_BEREICH" mappen. Wie das geht, verrät sicherlich die
Dokumentation zu Deiner Enrwicklungsumgebung
Das ganze funktioniert auch für den RAM-Bereich.
Also z.B.:
wenn ich Dich richtig verstehe muss ich also dem Compiler nur sagen wo
genau ich meine Variablen im RAM speichern will und dann sind die auf
dem Platz "festgenagelt" und damit ist dann sichergestellt, dass nach
einem update die Variablen wieder genau dort sind. Wäre ja einfacher als
ich mir vorgestellt hatte.
Danke,
Ingo
Wo die Variablen im RAM liegen ist doch Wurst, wenn du die neue Firmware
per (eigenem) Bootloader geflasht hast, musst du doch eh den µC neu
starten, dann werden auch alle Variablen usw. neu initialisiert. Wichtig
ist halt nur, dass dein eigener Bootloader und alles was dazu gehört, in
einem geschütztem Flash.Bereich kommt, den du dann natürlich nicht
überschreiben darfst. Ich mach das auch erfolgreich über Funk. Klappt
bestens.
Meinen "Bootloader" will ich ja auch in einen geschützen Bereich
schreiben, da ich diese Programmteile aber im normalen Programmablauf
mit nutzen will, muss ich doch irgendwie sicherstellen, dass die
Variablen die Bootloader und Programm gemeinsam nutzen immer an der
gleichen Stelle sind. Oder bin ich da auf dem Holzweg?
>wenn ich Dich richtig verstehe muss ich also dem Compiler nur sagen wo>genau ich meine Variablen im RAM speichern will und dann sind die auf>dem Platz "festgenagelt"
Ich weiß nicht genau was Du vorhast... aber so in etwa stimmt das.
Du musst aber zwei Dinge unterscheiden:
1.) Wenn Du einen Segment-Bereich festlegst, wird dieser z.B. für
Variablen oder speziellen Programmcode reserviert. Dem Linker ist es
aber freigestellt, wohin genau er was ablegt. Sicher ist nur, dass er es
in dem spezifizierten Bereich macht!
2.) Wenn Du z.B. eine Variable an einer ganz bestimmten Adresse haben
willst musst Du genau diese Adresse angeben, also z.B.:
1
#pragma location=0x0220
2
__no_initvolatilecharc_Meine_Variable;
Das funktioniert aber nur mit globalen (allenfalls noch mit statischen)
Variablen, denn lokale Var's werden entweder in Registern gehalten oder
wandern auf den Stack!
Es geht mir um die globalen Variablen, ich habe mich bestimmt nur
missverständlich ausgedrückt. Ich werde dass mal so probieren.
Danke für Eure Antworten
Ich habe da ein ähnliches Problem.
Also ich möchte etwa 20 16-Bit Variablen/Parameter im Flash speichern.
Diese soll man dann im normalen Programmablauf über UART
auslesen/löschen/verändern können.
Bisher habe ich noch nichts in der Richtung gemacht, was heisst, dass
das wirklich absolutes Neuland für mich ist.
Kann ich jetzt einfach in meinem C-Programm vor dem Main (also bei den
Includes etc.) meine Variablen/Parameter an einer bestimmten Position im
Flash festlegen?
Also irgendwie so wie oben beschrieben:
>Ich habe da ein ähnliches Problem.>Also ich möchte etwa 20 16-Bit Variablen/Parameter im Flash speichern.>Diese soll man dann im normalen Programmablauf über UART>auslesen/löschen/verändern können.
Leute... werdet euch bitte endlich mal darüber klar, was Variablen und
Konstanten sind! Die einen liegen im RAM und sind veränderlich, die
anderen liegen nicht-flüchtig im Flash und sind (ohne weiteres) nicht
veränderlich!
>Kann ich jetzt einfach in meinem C-Programm vor dem Main (also bei den>Includes etc.) meine Variablen/Parameter an einer bestimmten Position im>Flash festlegen?
1
>#pragmalocation=0x0220
2
>__no_initvolatilecharc_Meine_Variable
Nein, denn das landet ja im RAM und Du willst Deine Parameter sicherlich
nicht-flüchtig abspeichern, oder?
Mach's z.B so:
1.) einfach nur "Platzhalter" im Flash anlegen
1
#pragma location=MEINE_FLASH_ADR
2
__root__no_init
3
constintMyConst_1;
2.) Konstante mit Wertzuweisung
1
#pragma location=MEINE_FLASH_ADR_2
2
__root
3
constunsignedcharSoftwareVersion[5]=
4
{'0','8','.','1','5'};
Das _root ist wichtig, falls die Konstante z.B. im Programm nicht
explizit benutzt wird, um nicht "weg-optimiert" zu werden.
_root kann man zur Sicherheit immer verwenden, schaden tut's m.W. nicht!
Um die Parameter im Flash zur Laufzeit zu ändern, kannst Du aber jetzt
nicht einfach schreibend darauf zugreifen, sondern Du must den
Flash-Memory-Controller bemühen (s. User-Guide)!
Also ich habe eben Parameter (mit bestimmten Default Werten, welche
jedoch über UART geändert werden können) und dann auch Variablen (ohne
Default Wert, welche ständig ändern und einfach der aktuelle Wert über
UART ausgelesen werden kann).
Normale Parameter, die beim Starten des MSP430 einen Default-Wert
bekommen sollen, kannst du doch ganz normal als Variablen im RAM lassen,
halt bei der Deklaration gleich den Default-Wert mit dran:
volatile int TestVar = 100;
Wenn du die per UART geänderten Werte nach einem Neustart des MSP noch
haben willst, musst du die im Flash ablegen. Das geht dann aber nicht so
einfach, weil da immer das ganze Info-Flash-Segment gelöscht werden muss
vorher und dann müssen die über den Flash-Controller da reingeschrieben
werden. Das geht auch nur eine begrenze Anzahl.
Mal eine Frage:
Ich habe in meiner main.c Datei z.B. eine globale Variable deklariert.
1
__no_initINT32Sglobal_var
Wird diese so ins Flash gespeichert oder ins RAM bzw. kann man generell
sagen, dass alle im Programm "normal" deklarierten Variablen ins RAM
kommen und nur wenn ich explizit mit Flash-Memory-Controller etwas
mache, die Variablen dann im Flash sind?
>Wird diese so ins Flash gespeichert oder ins RAM bzw. kann man generell>sagen, dass alle im Programm "normal" deklarierten Variablen ins RAM>kommen und nur wenn ich explizit mit Flash-Memory-Controller etwas>mache, die Variablen dann im Flash sind?
Wennn der Compiler sieht das die Daten die du anlegst veränderbar sind,
wird daraus immer eine Variable die im RAM landet. Bei einer globale
Variable mit initialisierungswert (z.B. int i = 100;) wird die 100 zwar
im Flash gespeichert (wie das gesamte Programm halt auch), im
Programmablauf ist es aber eine Variable weil du sie so angelegt hast
das man sie ändern kann.
>Also ich habe eben Parameter (mit bestimmten Default Werten, welche>jedoch über UART geändert werden können)
Dann machst du
1
intWert=12345;
>und dann auch Variablen (ohne Default Wert, welche ständig ändern und>einfach der aktuelle Wert über UART ausgelesen werden kann).
Dann machst du