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!
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.