Hallo, ich habe mir kürzlich eine Lib zu ansteuerung eines Displays hier aus dem Forum geladen. Nun versuche ich, den Code nachzuvollziehen. Kann mir da vielleicht jemand kurz etwas Schützenhilfe geben. Folgende Passage ist mir nicht verständlich: #define lcd_string_P(__s) lcd_string(P(__s)) #ifndef P #define P(s) ({static const char c[] _attribute_ ((progmem)) = s;c;}) #endif #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif Danke und Gruß, Alex
:
Verschoben durch User
Du kennst #define-Makros? Nein: RTFM, in diesem Fall jedes beliebige C-Lehrbuch Ja: Du weisst, was progmem, sbi und cbi bedeuten könnten? Nein: RTFM, in diesem Fall das AVR-gcc-tutorial oben links Ja: Was ist dann noch unklar? Oliver
1 | > #define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;}) |
Wrapper für ne (GCC) Extension, damit kann man einen String innerhalb einer Funktion als prog_char* definieren und verwenden.
Danke, bis auf die Zeile in Martin's Post habe ich den Ret nach Oliver's freundlichem Hinweis verstanden. @Marin: kannst Du mir das kurz etwas genauer erläutern. Ich glaube Hintergrund der Codezeile ist, dass die Font-Datei der Lib im Programmspeicher des Controllers liegt. Das passt zumindest ach zu dem, was Du gerade geschrieben hast. Danke, Alex
Das sorgt lediglich dafür, dass der angegebene String im Flash des Controllers gespeichert wird und nicht im SRAM. Und zwar ohne dass man da lange großartige Verrenkungen mit Hilfsvariablen machen muss.
1 | lcd_string_P( "Hallo Welt" ); |
die Funktion lcd_string (also die Variante ohne P) bekommt einen Pointer der ins Flash zeigt und freundlicherweise wird auch gleich noch dafür gesorgt, dass an eben genau dieser Stelle im Flash der Text "Hallo Welt" zu liegen kommt.
Beispiel: Du schreibst:
1 | char* mytext = P("Hallo"); |
Der Präprozessor wandelt das um in:
1 | char* mytext = {static const char c[] __attribute__ ((progmem)) = "Hallo";c;} |
Das nutzt jetzt eine Spracherweiterung des Gnu-C-Compilers: Ein Block {...} hat den Wert seiner letzten Anweisung, in diesem Fall den Wert von c, und kann damit auf der rechten Seite einer Zuweisung stehen. c wird in der Anweisung davor als char-Array im Flash deklariert und initialisiert. Also steht da im Prinzip, zusammengefasst in einer Zeile:
1 | |
2 | static const char c[] __attribute__ ((progmem)) = "Hallo"; |
3 | char* mytext = c; |
nur das die Variable c in der Einzeilenfassung nach aussen nicht sichtbar ist. Oliver
Nachtrag: Dafür gibt es eigentlich seit ewigen Zeiten das Makro PSTR in der avrlibc. Oliver
Vielen Dank, das war einiger Input, den ich erst einmal einziehen lassen muss, aber ich hab schon verstanden, wo die Reise hingeht. Euch Vielen Dank, Alex
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.