Forum: Compiler & IDEs WinAVR: Makefile-Makros in String konvertieren


von Klausewitz (Gast)


Lesenswert?

Hallo,
ich stehe gerade etwas auf dem Schlauch...  :(

Ich möchte in meinem Binärcode ein paar Strings im Flash speichern, um 
später beim Auslesen zu erkennen, welches Programm da vorliegt. Also 
irgendwo im Binär-Dump sollte dann sowas wie "Plattform=S88" stehen.
Speichere ich ein "normales" String-Makro aus einer Header-Datei (z.B.
1
#define Hostname  "S88"
ab, funktioniert das auch mit PROGMEM wunderbar.

Aber mit Makros aus dem makefile funktioniert das nicht. Ich habe da 
z.B. eine Definition TARGETSYSTEM, die ich mit -D auch an gcc übergebe.
Die Abfrage in .c
1
#if TARGETSYSTEM==S88
funktioniert beim Compilieren auch einwandfrei. Aber wie kriege ich den 
Wert des Makros so als String konvertiert, daß ich ihn als 
Initialisierung mit PROGMEM benutzen kann? Also sowas wie:
1
const char t[] PROGMEM = TARGETSYSTEM;

Nächste Stufe: Wie kriege ich ein Makro mit einer Zahl (kennt der 
Präprozessor überhaupt den Unterschied von Zahl und String???) so 
konvertiert, daß er hinterher F_CPU nicht als 16000000, sondern als 
"1600000" interpretiert?

Wahrscheinlich ist die Lösung einfach, aber ich komme einfach nicht 
drauf. #TARGETSYSTEM kommt nicht zur Lösung und das Schlüsselwort 
STRINGIZE scheint auf Keil beschränkt zu sein?!
LG Klausewitz

von Stefan E. (sternst)


Lesenswert?

Entweder im C-Source in einen String wandeln:
1
#define STRx(s) #s
2
#define STR(s) STRx(s)
3
4
const char t[] PROGMEM = STR(TARGETSYSTEM);

Oder gleich im Makefile als String definieren:
1
-DTARGETSYSTEM=\"S88\"

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klausewitz schrieb:
> kennt der Präprozessor überhaupt den Unterschied von Zahl und String?

Der Präprozessor kennt erstmal nur Makros.  Das sind sture Ersetzungen
eines Namens durch das, was bei der Definition des Makros als Wert
angegeben worden ist.

Der Präprozessor kennt auch einen Datentyp, nämlich int (ggf. auch als
long int, wenn nötig), aber der wird ausschließlich als Argument einer
#if-Anweisung benutzt um zu ermitteln, ob der Wert jetzt wahr (!= 0)
oder falsch (== 0) ist.

Als Spezialfälle kann der Präprozessor in einem Makro auch zwei Namen
miteinander verketten, sodass sie später dem Compiler als ein einziger
Name übergeben werden (so kann man beispielsweise aus »PORT« und »A«
auch »PORTA« basteln), sowie die dir eben gezeigte Möglichkeit, einen
Namen in einen String umzuwandeln.  Dafür dienen die Operatoren ## und
#.

von Klausewitz (Gast)


Lesenswert?

Verdammt, kaum macht man's richtig, schon gehts!  :)
Vielen Dank!!!

Das im Makefile als String zu übergeben habe ich auch versucht - hätte 
wohl auch geklappt, wenn ich es mit \"S88\" versucht hätte statt "S88". 
an den Kopf hau
Die Idee mit den STRx()-Makros ist super.

Irgendwie hatte ich mir auch schon gedacht, daß der Präprozessor 
eigentlich nur Text in einer Text-Datei ersetzt (salopp gesprochen). 
Aber keine Frage ist zu dumm, als daß sie nicht doch jemand stellt. ;)

Nochmal danke!

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.