Kleines Problem mit Includes

Gast #737943
Lesenswert?

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
Angehängte Dateien:
Moderator Persönliche Seite #737951
Lesenswert?

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.
Gast #737953
Lesenswert?

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?
#737958
Lesenswert?

@ 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
Moderator Persönliche Seite #737963
Lesenswert?

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.
#737993
Lesenswert?

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
#738126
Lesenswert?

@ 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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren