Hallo, ich muss ein bzw. zwei Bytes in ein Programm einfügen, welche nicht im Programm verwendet werden, aber dennoch beim Kompilieren nicht wegoptimiert werden dürfen. Wie mache ich das? Meine Versuche mit static, const und/oder volatile führten leider zu nichts.
static uint16_t __attribute__((used)) dummy = 123; So? Leider bleibt die Größe des Binarys gleich. Die Bytes sind also nicht drin.
Sollte klappern, zumindest laut Doku. Hier gehts augenscheinlich auch:
1 | $ cat test.c ; for x in used unused ; do gcc -O3 -o test_$x -DUSED="__attribute__(($x))" test.c ; done ; size test_* |
2 | static int i00 USED = 0; |
3 | static int i01 USED = 1; |
4 | static int i02 USED = 2; |
5 | static int i03 USED = 3; |
6 | static int i04 USED = 4; |
7 | static int i05 USED = 5; |
8 | static int i06 USED = 6; |
9 | static int i07 USED = 7; |
10 | static int i08 USED = 8; |
11 | static int i09 USED = 9; |
12 | |
13 | int main() |
14 | { |
15 | return 0; |
16 | } |
17 | |
18 | text data bss dec hex filename |
19 | 1107 552 8 1667 683 test_unused |
20 | 1107 588 12 1707 6ab test_used |
Hmpf, hier wird's rausoptimiert. Beißt sich das vielleicht mit -fdata-sections?
Du linkst wohl mit -gc-sections? Dann ein KEEP im Linker-Script oder ein -u für den Linker. Ob die Variable den Compiler überlebt hat siehst du im .s von -save-temps. Beil älteren GCC-Versionen wirkt used nur bei Funktionen.
Volatile war schon mal richtig, aber mindestens einmal muß die Variable m.E. gelesen werden, damit sie zuverlässig drin bleibt.
1 | volatile const int konstanze = 0x100; |
2 | |
3 | /* ... später irgendwo im Programm ... */
|
4 | (void) konstanze; |
müsste unabhängig vom Opimierungs-Level - auch ohne _attribute_ - ausreichen, die "variable Konstante" im Programm zu halten. Der Compiler kann nicht wissen, ob der Dummy-Read nicht irgendein Hardware-Register mit Seiteneffekt trifft und muß den Aufruf drinlassen.
:
Bearbeitet durch User
nicht"Gast" schrieb: > moin, > > wozu braucht man so was? Wen man z.B. eine Versionsnummer oder ein build-Datum im Binary halten will (um verschiedene Versionsstände im Feld auseinanderhalten zu können).
Markus F. schrieb: > Wen man z.B. eine Versionsnummer oder ein build-Datum im Binary halten > will (um verschiedene Versionsstände im Feld auseinanderhalten zu > können). Wenn man so was macht, sollte man doch auch eine Funktion einbauen, den Stand abzufragen oder? Man kann ja schlecht den Kunden bitten, mal eben in Binary der Software zu schauen oder gar erst vom Chip runter zu holen. Grüße
nicht"Gast" schrieb: > Wenn man so was macht, sollte man doch auch eine Funktion einbauen, den > Stand abzufragen oder? Zumindest in den früher gerne verwendeten Sourcecode-Verwaltungen wie sccs und cvs war sowas üblich. Auch ohne Anzeige. Es reichte, wenn die entsprechenden Versions-Strings irgendwo im Binary lagen. Dafür gab es ein Programm, dass diese Strings in Files anzeigte. Auch da begegnete man mit dem Aufkommen von optimierenden Compilern und Linkern allerdings genau dem beschriebenen Problem, also den verschwindenden Strings.
:
Bearbeitet durch User
nicht"Gast" schrieb: > Markus F. schrieb: >> Wenn man z.B. eine Versionsnummer oder ein build-Datum im Binary halten >> will (um verschiedene Versionsstände im Feld auseinanderhalten zu >> können). > > Wenn man so was macht, sollte man doch auch eine Funktion einbauen, den > Stand abzufragen oder? Man kann ja schlecht den Kunden bitten, mal eben > in Binary der Software zu schauen oder gar erst vom Chip runter zu > holen. Wenn der Kunde fünf verschiedene Binaries zur Auswahl auf seinem PC hat und wissen will, welches davon er brennen soll, bringt die Funktion im Binary selbst nicht sooo viel. Ein kleines PC-Progrämmchen, das die Versionsnummer auslesen kann, um so mehr ;)
Also, so richtig funktioniert das nicht. Ich verwende avr-gcc. Leider wird die Konstante mit Opcodes vermischt und auf mehrere Bytes verteilt. "Das" Byte oder Word steht jedenfalls nicht mehr 1:1 drin. Ich klatsche es jetzt nachträglich an eine nop-Stelle in der Interrupt-Tabelle... spart sogar Platz und die Position ist fix. :P
So hab ich das gemacht: 1. Im Linkerfile eine eigene Section mit "KEEP" angelegen:
1 | .proj_ident : |
2 | {
|
3 | . = ALIGN(4); |
4 | KEEP(*(.proj_id0)) |
5 | . = ALIGN(4); |
6 | } >PROJIDENT |
2. Im Linkerfile diese Section an eine feste Adresse legen. 3. Im Code die gewünschte Konstante in diese Section hinein tun:
1 | volatile const uint32_t proj_id0_u32 __attribute__ ((section (".proj_id0"))) = 0xCAFEAFFE; |
Dann kann man die Konstante auch recht einfach aus dem Hexfile lesen.
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.