Forum: Mikrocontroller und Digitale Elektronik Variable an vorgegebene adresse legen


von John (Gast)


Lesenswert?

Habe folgende Frage

Ich möchte gerne, dass eine Variable vom linker an eine bestimmte 
Adresse gemappt wird.

Gibt es eine Möglichkeit dies dem GCC mitzuteilen?

Ich weiss, dass ich mit (adresse)* auf einen speicherbereich zugreifen 
kann. Dies ist jedoch nicht das was ich möchte. Denn in diesem Fall kann 
es ja sein, dass dieser Speicherplatz bereits von etwas anderem belegt 
wird...

Danke schonmal

von mukel (Gast)


Lesenswert?

Neue Section im linkerscript anlegen und deinem Kompiler über ein 
Attribut mitteilen, das er die variable in der section platzieren soll. 
Linkerscript und die Attributdefinitionen hängen vom Compiler ab.

Wenn du uns deine Anwendung und deine Plattform/Toolchain/Compliler 
mitteilst, kann dir besser geholfen werden.

von MaWin (Gast)


Lesenswert?


von John (Gast)


Lesenswert?

Vielen Dank für eure Antworten.
Plattform ist ein ESP8266
IDE ist sloeber...

von Einer K. (Gast)


Lesenswert?

Woher weist du, dass der Kompiler deine Wunschadresse nicht noch für 
andere Zwecke verwendet?

von John (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Woher weist du, dass der Kompiler deine Wunschadresse nicht noch
> für andere Zwecke verwendet?

Genau das ist ja das problem...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenns nur eine Variable ist, kann man evtl. auch ein Register dafür 
verwenden:
1
register volatile uint16_t sineTableIncrement asm ("r2");

Hier mal für den AVR.

von Jdhdiebdkx (Gast)


Lesenswert?

Wenn du c++ verwendest kannst du dir "placement new" mal anschauen. 
Kommt ganz ohne Pragmas oder den linker aus und funktioniert daher auf 
jedem Compiler Out of the Box.

Beitrag #6023559 wurde von einem Moderator gelöscht.
von Stefan F. (Gast)


Lesenswert?

John schrieb:
>> Woher weist du, dass der Kompiler deine Wunschadresse nicht noch
>> für andere Zwecke verwendet?
>
> Genau das ist ja das problem...

Ja dann lass das doch bleiben! Wenn du nicht weißt, ob die Adresse frei 
ist, hast du auch keinen guten Grund, die Variable ausgerechnet dorthin 
zu legen.

von Stefan F. (Gast)


Lesenswert?

Matthias S. schrieb:
> Wenns nur eine Variable ist, kann man evtl. auch ein Register dafür
> verwenden

Die Wahrscheinlichkeit, dass die Firmware des ESP8266 ein Register 
unbenutzt lässt, geht gegen Null.

von Einer K. (Gast)


Lesenswert?

Stefan F. schrieb:
> keinen guten Grund

Das würde mich auch interessieren, das Endziel der Übung...
Der Sinn, der Zweck, der Grund, warum das muss.
z.B. eine Begründung, warum malloc() und Pointer nicht reichen.

Dann könnte man evtl. eine Alternative benennen.

von John (Gast)


Lesenswert?

Ok ich habs verbokt liebe leute... eigentlich wollte ich eine konstante 
an einer bestimmten adresse im flash abspeichern. Keine variable.

Asche auf mein Haupt. Sorry, dass ich mich so undeutlich ausgedrückt 
habe...

Also: ich möchte mit meinem programm immer an der selben adresse nach 
abgleichwerten zugreifen können. Die abgleichwerte werden zuvor durch 
eine externe applikation in mein firmware image geschrieben und dann das 
image geflasht.

Die firmware soll dann zb an addr 0x1234 auf die kalibwerte zugreifen...

von Nils (Gast)


Lesenswert?

Du kannst im Linker Script einfach ein Teil des Flash Address Bereiches 
auslassen. Der Linker und Compiler ignoriert diesen Bereich dann 
komplett.

Du kannst dann mit dem Flash Bereich machen, was Du willst.

Ist ein bischen frickelig, wenn sich der Speicherbereich in der Mitte 
des Flash Addressraums befindet. Dann musst Du die beiden Segmente, die 
für Code genutzt werden Gruppieren. Geht, nervt aber.

Besonders wird es, wenn Du Deinen reservierten Bereich einfach an das 
Ende des Flash legst. Dann brauchst Du nur die Größe des Flash Speichers 
im Linkerscript reduzieren und gut ist.

von Einer (Gast)


Lesenswert?

Speichere vor deiner Konstante eine magic number ab.
Die kannst du dann mit deiner externen Applikation
im Image suchen und ändern.

von Axel S. (a-za-z0-9)


Lesenswert?

John schrieb:
> ich weiss, dass ich mit (adresse)* auf einen speicherbereich zugreifen
> kann. Dies ist jedoch nicht das was ich möchte. Denn in diesem Fall kann
> es ja sein, dass dieser Speicherplatz bereits von etwas anderem belegt
> wird

Nein.

Das ergibt keinen Sinn. Wenn du eine Variable fest an eine Adresse 
binden willst, dann ist das typisch ein IO-Register. Auf jeden Fall eine 
Adresse außerhalb des Datensegments (das vom Compiler verwaltet wird). 
Es gibt schlicht keinen Grund, eine Adresse innerhalb des 
Datensegments fest für eine Variable reservieren zu wollen. Deswegen 
kann es auch eine derartige Kollision nicht geben.

Und falls doch, dann soltest du jetzt eine Begründung liefern. Und 
zwar eine verdammt gute.

Für alle praktischen Fälle reicht ein bißchen Makro-Magie, um Zugriffe 
auf Speicher an einer festen Adresse wie einen normalen Variablenzugriff 
aussehen zu lassen. Die Headerfiles, die die IO-Register eines µC 
definieren, geben genügend Hinweise darauf, wie man das richtig macht.


(Zeitüberschneidung)

John schrieb:
> .. eigentlich wollte ich eine konstante
> an einer bestimmten adresse im flash abspeichern. Keine variable

Vollkommen egal. Warum muß deine Konstante an einer bestimmten Adresse 
liegen? In C ist das Konzept "Adresse" weitgehend überholt und wird 
abgelöst von "Variablenname". Bzw. in dinem Fall Konstantenname.

Jede Variable (oder benannte Konstante) bekommt vom Compiler ein Symbol 
zugewiesen und ist über den Symbolnamen nicht nur aus C, sondern auch 
aus Assembler problemlos zu erreichen. Es gibt genau gar keinen Grund, 
den Speicherort händisch festlegen zu wollen. Überlaß das dem Compiler.

: Bearbeitet durch User
von Klaro (Gast)


Lesenswert?

Axel S. schrieb:
> Es gibt genau gar keinen Grund,
> den Speicherort händisch festlegen zu wollen. Überlaß das dem Compiler.

Er hat doch den Grund genannt und hier steht die Antwort auf die 
ursprüngliche Frage:
MaWin schrieb:
> Na so
> 
https://mcuoneclipse.com/2012/11/01/defining-variables-at-absolute-addresses-with-gcc/
> oder so
> https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Variable-Attributes.html


Ein weiterer, gleich gearteter Grund das tun zu wollen, ist z.B. die 
Checksumme über das Image des Programms von einem Skript an eine feste 
Adresse schreiben zu lassen, die das Programm dann verwenden kann, um 
sich selbst zu prüfen.

von Jim M. (turboj)


Lesenswert?

Einer schrieb:
> Speichere vor deiner Konstante eine magic number ab.
> Die kannst du dann mit deiner externen Applikation
> im Image suchen und ändern.

Blöde Idee, denn man kann bei Flash immer nur einen ganzen Sektor 
löschen.

Außerdem kann Dir dann der Optimizer dazwischen funken.

Besser ist das Reservieren eines Flash Sektors (oder mehrere) im Linker 
Skript. Entweder am Ende (s.o.) oder hinter den Interrupts, die ja 
meistens am Anfang des Flash stehen und i.d.R. ohnehin gesondert 
behandelt werden.

von Einer (Gast)


Lesenswert?

Jim M. schrieb:
> Blöde Idee, denn man kann bei Flash immer nur einen ganzen Sektor
> löschen.

Nicht richtig gelesen.
Er wollte das vorm flaschen per Programm patchen.

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
Noch kein Account? Hier anmelden.