Hallo,
weiß einer wo es bescrieben steht, wie ich eine Variable auf einer
definierten Adresse erstellen kann? Hintergrund ist, dass ein TEil vom
RAM bei einem Reset nicht gelöscht wird. Dort muss ich ein FLAG setzen,
welches nach einem Reset abgefragt werden muss. Allerdings habe ich
keine Ahnung, wie ich sagen kann, dass die Variable xy an Adresse xyz
erstellt werden soll.
Du kannst das mit volatilen pointern machen. Volatil, damit der Compiler
Dir nicht Deine Leseoperationen wegoptimiert, also z.B.:
1
*(volatileuint8_t*)0x12345678u=1;// write
2
intvar=*(volatileuint8_t*)0x12345678u;// read
Wenn Dir das zu hässlich ist, dann baust DU halt ein Define drumherum:
1
#define MY_VAR (*(volatile uint8_t*)0x12345678u)
2
3
MY_REGISTER=1;// write
4
intvar=MY_REGISTER;// read
Oder wenn Du mehrere Variablen hast und C++ verwendest, dann machst Du
halt ne Klasse draus (wobei DU hier auch noch volatile setzen musst, so
wie Dein compiler das zulässt):
1
classMyMem
2
{
3
public:
4
uint32_tsomePort;
5
uint32_tsomeOtherPort;
6
};
7
8
classMyMem*mem=(MyMem*)(uintptr_t)0x12345678;
9
10
mem->somePort=100;
11
uint32_tdata=mem->someOtherPort;
Du kannst auch weit auseinander liegende Speicherstellen so belegen, da
ja Dein Klasse nie alloziert wird, also:
1
classMyMem
2
{
3
public:
4
uint32_tPORT_A;
5
uint32_toffset_zu_b[1023];// A, B und C sind 4096 bytes auseinander
Matthias M. schrieb:> class MyMem *mem = (MyMem*)(uintptr_t)0x12345678;
So legst du zwar die Speicheradresse fest, aber du allokierst sie nicht.
Der Compiler/Linker könnte den Speicherbereich daher bereits anderweitig
verwendet haben (wenn es sich um RAM und nicht um Hardware-Register
handelt). Das gibt ganz tolle Fehler, viel Spass beim Suchen.
Sven P. schrieb:> Der eigentlich (fast) einzig sinnvolle Weg mit zeitgemäßen Compilern> ist, das Symbol im Linkerskript festzunageln.
Genau, zusammen mit dem attribut
Michael D.
Ich habe die Variable absichtlich nicht alloziert, da solche Tricks ja
eigentlich nur nötig sind, um auf Hardwareregister zuzugreifen, und dann
wäre eine Allokation falsch.
Auch in allen anderen Fällen, die wohl eher nicht in den Mikrocontroller
Bereich gehören, so wie Shared Memeory, MMU und DMA Aufgaben wäre der
Speicher ja bereits anderweitig alloziert worden.
Aber wenn es da noch einen anderen Fall gibt, dann würde mich das sehr
interessieren.
Sven P. schrieb:> Der eigentlich (fast) einzig sinnvolle Weg mit zeitgemäßen Compilern> ist, das Symbol im Linkerskript festzunageln.
Oder die beiden unterschiedlichen RAM-Bereiche in separate Sektionen zu
stecken und beim Anlegen der Variablen die gewünschte Sektion anzugeben.
MatthiasM schrieb:> Ich habe die Variable absichtlich nicht alloziert, da solche Tricks ja> eigentlich nur nötig sind, um auf Hardwareregister zuzugreifen, und dann> wäre eine Allokation falsch.
Die Variable soll nicht allokiert werden, sondern es muss sichergestellt
sein, dass sie nicht im Pool, den der Compiler zur freien Verwendung
hat, enthalten ist.
> Aber wenn es da noch einen anderen Fall gibt, dann würde mich das sehr> interessieren.
Der steht doch im Ursprungsposting:
Johannes schrieb:> Hintergrund ist, dass ein TEil vom RAM bei einem Reset nicht gelöscht> wird. Dort muss ich ein FLAG setzen, welches nach einem Reset abgefragt> werden muss.
Julian Mettler schrieb:> Wie Fanboy schon sagt. Du musst einfach eine Variable> in der .noinit section anlegen.
Dann bekommt er eine nicht initialisierte Variable irgendwo im Speicher,
aber ganz sicher nicht an der Stelle, an der er das Flag für den
Bootloader setzen muss.
Dieser Vorschlag geht am Problem vorbei.
Ein Beispiel, um direkt in den Arduino "Caterina" Bootloader (AVR) zu
springen:
S. R. schrieb:> aber ganz sicher nicht an der Stelle, an der er das Flag für den> Bootloader setzen muss.
Das ist ja eine lustige Anforderung....
Wie kommst du darauf?
Bisher war noch nicht mal von AVR die Rede...
Geschweige denn vom 32U4 oder Bootloader
Arduino Fanboy D. schrieb:> S. R. schrieb:>> Dann bekommt er eine nicht initialisierte Variable irgendwo im>> Speicher, aber ganz sicher nicht an der Stelle, an der er das Flag für>> den Bootloader setzen muss.>> Das ist ja eine lustige Anforderung....> Wie kommst du darauf?
Schauen wir uns die Frage des TO doch mal an:
Johannes schrieb:> weiß einer wo es bescrieben steht, wie ich eine Variable auf einer> definierten Adresse erstellen kann?
Da steht zwar nichts von einem Bootloader, aber dass die Variable an
einer ganz bestimmten Adresse stehen soll.
Rolf M. schrieb:> aber dass die Variable an> einer ganz bestimmten Adresse stehen soll.
Dafür wurden Pointer erfunden! (wenn mich nicht alles täuscht)
Und die wurden hier schon durchgekaut.
Matthias M. schrieb:> verbraucht 0 bytes Speicher.
Und ist den meisten Fällen undefined behavior und wenn nicht darf der
Compiler vermutlich alles wegoptimieren.
Arduino Fanboy D. schrieb:> Dafür wurden Pointer erfunden! (wenn mich nicht alles täuscht)> Und die wurden hier schon durchgekaut.
Na also, jetzt bist du schon einen Schritt weiter. Mach noch einen, und
dann bist du auch so weit, wie der Rest hier.
Rolf M. schrieb:> Mach noch einen, und> dann bist du auch so weit, wie der Rest hier.
Häää...
Bisher ist mir nur klar, dass eine Variable(besser: ihr Inhalt), einen
Reset überleben soll.
Alles andere ist Kaffeesatzleserei.
Macht das, wenn es Spaß macht.....
Ich warte lieber auf etwas konkretere Informationen.
Arduino Fanboy D. schrieb:> Rolf M. schrieb:>> Mach noch einen, und>> dann bist du auch so weit, wie der Rest hier.>> Häää...>> Bisher ist mir nur klar, dass eine Variable(besser: ihr Inhalt), einen> Reset überleben soll.
Ich zitiere nochmal die initiale Frage des TO:
Johannes schrieb:> weiß einer wo es bescrieben steht, wie ich eine Variable auf einer> definierten Adresse erstellen kann?
Wenn ich dann davon ausgehe, dass er wissen will, wie er eine Variable
auf einer definierten Adresse erstellen kann, würde ich das nicht als
Kaffeesatzleserei bezeichnen.
Rolf M. schrieb:> Ich zitiere nochmal die initiale Frage des TO:
Und ich zitiere den initialen Irrtum des TE.
Johannes schrieb:> Hintergrund ist, dass ein TEil vom> RAM bei einem Reset nicht gelöscht wird. Dort muss ich ein FLAG setzen,> welches nach einem Reset abgefragt werden muss.
Zumindest in der AVR gcc Welt kann man davon ausgehen, dass Speicher bei
einem Reset nicht gelöscht wird.
Allerdings werden (nicht lokale) Variablen üblicherweise initialisiert.
Nur eben nicht in der .noinit Section, woher sie ja auch ihren Namen
hat.
Johannes schrieb:> Allerdings habe ich> keine Ahnung, wie ich sagen kann, dass die Variable xy an Adresse xyz> erstellt werden soll.
Wenn man in C oder C++ eine Variable erstellt, bekommt sie auch einen
Speicherplatz zugewiesen. Spätestens vom Linker.
Die Frage, warum dieser Variablen händisch eine Adresse vorgegeben
werden muss, ist hier für mich noch nicht geklärt.
Könnte eine überflüssige Bedingung sein, basierend auf einer weiteren
irrtümlichen Annahme, da ja der Compiler/Linker das durchaus selber
erledigen kann.
Und muss es wirklich händisch sein, dann geht der Weg eben über Pointer
Arduino Fanboy D. schrieb:> Die Frage, warum dieser Variablen händisch eine Adresse vorgegeben> werden muss, ist hier für mich noch nicht geklärt.
Einen möglichen Grund hatte ich genannt: Kommunikation mit dem
Bootloader. Genau da tritt ein solches Problem auf und die Frage des TO
in Bezug auf Reset lässt darauf schließen, dass es darum geht.
Arduino Fanboy D. schrieb:> Also doch: Kaffeesatzleserei.
Also ist es deiner Meinung nach besser, garnichts zu sagen und den TO
allein stehen zu lassen, als eine möglicherweise passende Lösung zu
posten.
Verstehe.
Arduino Fanboy D. schrieb:> Zumindest in der AVR gcc Welt kann man davon ausgehen, dass Speicher bei> einem Reset nicht gelöscht wird.
Aha, und das ist also im Gegensatz zur Beantwortung der ursprünglichen
Frage keine Kaffeesatzleserei?
S. R. schrieb:> Also ist es deiner Meinung nach besser, garnichts zu sagen und den TO> allein stehen zu lassen, als eine möglicherweise passende Lösung zu> posten.
Nunja...
Offensichtlich habe ich das Gegenteil deiner Behauptung schon längst
getan:
Arduino Fanboy D. schrieb:> Vielleicht möchtest du die Variable in der .noinit Section erstellen?
Mir reicht das erstmal an Kaffesatzleserei...
Solange der TE nicht etwas mehr Information liefert.