Moin! Bei meinem aktuellen AVR-Projekt (ich benutze AVR-GCC) habe ich ein kleines Problem mit Include-Files. Ich habe eine Datei "strings.h", die ein paar in anderen Includes verwendete Konstanten enthält. Die möchte ich gerne in die "main.h" packen. Doch dann bekomme ich X Fehlermeldungen, weil die Konstanten dann anscheinend mehrfach definiert sind. Jetzt muss ich das #include "strings.h" direkt in die main.c schreiben, dann gehts. Nur zweifle ich jetzt irgendwie an der Wirksamkeit dieser "Header-Guards" (#ifndef __STRINGS.H__ #define ... #endif).. Kann hier jemand vllt. kurz einen Blick in meinen Code werfen und mir sagen, wie ich das mit den Includes am besten löse? Die entsprechenden Dateien (sind nur ein paar) habe ich angehängt. Ich bin leider noch ein C-Anfänger und bekomme es wirklich nicht besser hin.. Wenn mir jemand helfen und sagen könnte, was Sache ist, wäre ich ihm sehr verbunden. ;-) Gruß und guten Rutsch, Paul
Die header guards sind OK, aber bitte benutze keine Namen mit führenden Unterstrichen, diese sind für die Bibliothek und den Compiler reserviert. Schreib also:
1 | #ifndef STRINGS_H
|
2 | #define STRINGS_H
|
3 | |
4 | // ...
|
5 | #endif /* STRINGS_H */ |
strings.h ist übrigens kein sehr schöner Name, da die Verwechslungs- gefahr mit dem Standard-C-Header string.h ziemlich groß ist.
Hi Jörg, erstmal danke für deine Antwort! Ich hab gelesen, dass die Unterstriche besser wären, weil der Compiler DEFINEs mit einem führenden E z.B. für sich beansprucht (irgendwie so). Oder macht AVR-GCC da eine Ausnahme? Danke für den Tipp, werde die strings.h auch nochmal umbenennen. ;) Aber wie bekomme ich es nun hin, dass ich das #include "strings.h" in die main.h schreiben kann? Ich bin, wie gesagt, sehr unsicher mit diesen ganzen includes. Vllt kann man das besser lösen?
@ Paul (Gast) >Aber wie bekomme ich es nun hin, dass ich das #include "strings.h" in >die main.h schreiben kann? ??? Schreibs doch einfach rein.
1 | #inlcude "my_strings.h"
|
>Ich bin, wie gesagt, sehr unsicher mit diesen ganzen includes. Vllt kann >man das besser lösen? Ja. Deine Fehler liegen a) and er falschen Syntax: in WINAVR wird das so gemacht. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29 b) am falschen Konztept. Was du in deiner string.h hast sind globale Variablen. Die werden anders gehandhabt. Stichwort EXTERN. in my_string.h kommt dann
1 | // Deklaration der globalen Variablen
|
2 | extern char hello[] PROGMEM; |
In my_string.c kommt dann
1 | // Definition der globalen Variablen
|
2 | char hello[] PROGMEM = "Hallo Welt!"; |
my_string.h kannst du dann überall problemlos einbinden. Solche globalen Variabeln bzw. Konstanten legt man üblicherweise in globals.c/h ab. MFG Falk
Paul wrote: > Ich hab gelesen, dass die Unterstriche besser wären, weil der Compiler > DEFINEs mit einem führenden E z.B. für sich beansprucht (irgendwie so). Makros, die mit einem E beginnen, sind in der Tat potenzielle Erweiterungen für <errno.h>. Allerdings haben wir davon im Moment beim AVR-GCC fast keine in Benutzung. Nur: du hast den Teufel mit dem Beelzebub ausgetrieben. Während die mit dem E für weitere Fehlernamen reserviert sind (wobei mir keiner bekannt ist, der davon jemals auf _H enden würde), sind die Makronamen, die mit einem Unterstrich und einem Großbuchstaben beginnen sowie alle Bezeichner, die mit zwei Unterstrichen beginnen, immer für die interne Benutzung von Compiler und Bibliothek reserviert.
Mensch..hab ganz vergessen, dass ich hier ja auch angemeldet bin. ;-) Danke euch! Es klappt jetzt alles so wie ich es haben will. Die letzte verbliebene Frage ist nur noch, in was ich diese Zeile umändern muss, wenn ich prog_char gänzlich vermeiden möchte:
1 | void print(const prog_char *str) |
Ganze Funktion:
1 | void print(const prog_char *str) |
2 | {
|
3 | while (1) { |
4 | char lsb = (char) pgm_read_byte(str); |
5 | if (lsb == '\0') |
6 | return; |
7 | remote_control(0, lsb); |
8 | str++; |
9 | }
|
10 | }
|
Gruß, Paul
@ Paul Wilhelm (mosfetkiller) >Die letzte verbliebene Frage ist nur noch, in was ich diese Zeile >umändern muss, wenn ich prog_char gänzlich vermeiden möchte: >void print(const prog_char *str) Du must einen Pointer auf Daten im Flash verweden. Hab aber im Moment die Doku nicht parat. Steht alles recht gut erklärt in der Doku der libc im WINAVR. Irgendwas mit PROGMEM_P oder so. MFG Falk
Na super ;-) Auszug aus dem PROGMEM-Kapitel der libc-Doku:
1 | #define PGM_P const prog_char ∗
|
Hat sich also erledigt. :P Aber trotzdem danke. Damit wären alle meine Fragen bis auf weiteres beantwortet! Gruß, Paul
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.