Forum: Mikrocontroller und Digitale Elektronik STM32, GCC: Konstanten im Flash


von anon (Gast)


Lesenswert?

Hallo,

reicht es aus, eine globale Variable als const zu deklarieren, damit der 
GCC sie bei einem STM32 Target in dessen Flash-Speicher packt und nicht 
ins RAM läd? Also etwa:
const unsigned char s[]="String im Flash zum dynamischen Laden";

Sollte das so gehen, so müsste man ja etwa wie folgt auf einzelne Bytes 
des Strings zugreifen können, da Flash und RAM sich einen gemeinsammen 
Adressraum teilen (und nicht wie bei der AVR-Architektur mit einem 
pgm_read_byte Äquivalent arbeiten):
unsigned char c;
c=s[2];


Vielen Dank schon einmal!

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich mache das immer so:
1
const <Datentyp> <variable>[] __attribute__ ((section(".rodata"))) =
2
{
3
: : :
4
};
5
6
#define  <variable>_ANZAHL (sizeof(<variable>)/sizeof(<Datentyp>))

Mit dem _attribute_ section wird es garantiert in den Bereich gelinkt 
wie im Linkerfile angegeben. Man kann somit selbst festlegen ab welcher 
Adresse die Daten stehen.

Bei einem reinen const bin ich mir auch nicht sicher wohin er die 
Konstante linkt. Steht aber in der .map Datei.

von (prx) A. K. (prx)


Lesenswert?

GCC legt solche Daten schon von sich aus nach .rodata, eine explizite 
Attributierung ist dafür nicht erforderlich. Wo diese Section allerdings 
abschliessend landet ist Sache des Linker-Scripts, nicht des Compilers.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Bei const bin ich mir nicht ganz sicher, ob die Ursprünglichen Daten im 
Flash liegen und bei Startup die Variable im Ram angelegt/Daten kopiert 
werden und der Zugriff in der Applikation erfolgt dann aus der RAM 
Kopie.

Ich glaube es gibt dazu auch einen Kompillerschalter.

Es kann auch sein ich verwechsle es gerade mit dem GCC Kompiller für den 
Atmega.

von (prx) A. K. (prx)


Lesenswert?

Den Compiler selbst geht das überhaupt nichts an. Der schiebt seine 
"const" Daten nach ".rodata" und die Sache hat sich für ihn. Ob das im 
Flash liegt, im RAM oder in externem DRAM ist ihm dabei völlig wurscht. 
Der Compiler weiss nicht einmal, ob der Controller überhaupt Flash hat.

Erst Linker-Script und Startup-Code bestimmen was damit passiert. Oft 
wird man bei ARMs mit Code im Flash auch die RO-Daten dorthin legen. 
Aber da bei Prozessoren ohne Cache der Zugriff auf Flash langsamer als 
RAM ist kann man das ggf. auch anders halten und den Linker so 
dirigieren, dass er diese Section im RAM platziert und der Startup-Code 
den Inhalt zusammen mit den normalen initialisierten Daten aus dem Flash 
dorthin kopiert.

Es gibt also keine einfache Antwort darauf (bei AVRs gibt es die, aber 
da ist das von der Architektur vorgegeben). Schon garnicht, wenn nur 
"GCC" in der Frage steht, nicht aber die konkrete Entwicklungsumgebung. 
Bei fertigen Compiler-Paketen wie Keil, Crossworks usw. wird man 
abhängig vom exakten Zielprozessor und dem Debugging-Modus eine 
bestimmte vorgesehene Verhaltensweise finden. Bei Bausätzen wie 
CodeSourcery und Yagarto, in denen der Anwender Linker-Script und 
Startup-Code ohnehin selbst definiert, ist alles offen.

Oft findet man optionale Szenarien für Debugging im RAM. Bei diesen ist 
alles im RAM, ob "const" oder nicht. In anderen Szenarien sind "const" 
Daten dann evtl. im Flash. Beim gleichen Compiler, beim gleichen 
Zielcontroller.

Klar ist nur, dass eine explizite Attributierung als .rodata genau das 
herstellt, was der Compiler von sich aus sowieso schon tut. Und damit 
keineswegs sichergestellt ist, dass diese Daten im Flash landen.

von Anon (Gast)


Lesenswert?

Vielen Dank für eure Ausführungen!

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.