AVR-GCC: Globales Include

Gast #4494925
Lesenswert?

Der Hintergrund meiner Frage:

In einer Quelltextdatei SoftSerial.c ändern sich zwei Pin (TxD, RxD) je 
nach Projekt.

Nun möchte ich in einer globalen hardware.h die Pins ablegen (z. B. 
#define TxD PORTB1).

Wie kann ich das elegant lösen ohne SoftSerial.c zu verändern oder zu 
kopieren?
Gast #4494928
Lesenswert?

GCCUser schrieb:
> Der Hintergrund meiner Frage:
>
> In einer Quelltextdatei SoftSerial.c ändern sich zwei Pin (TxD, RxD) je
> nach Projekt.
>
> Nun möchte ich in einer globalen hardware.h die Pins ablegen (z. B.
> #define TxD PORTB1).
>
> Wie kann ich das elegant lösen ohne SoftSerial.c zu verändern oder zu
> kopieren?

Warum solltest du das müssen? Du musst doch nur dein hardware.h ändern.
Gast #4494934
Lesenswert?

Du könntest es mit dem Compiler machen als Parameter -DTxD=PORTB1 beim 
gcc.
In der Quelldatei dann noch sicherstellen, dass Txd definiert ist und 
einen Fehler ausgeben, wenn das nicht der Fall ist #ifndef TxD usw.
So ist der Quellcode identisch und du kannst in den 2 Projekten über den 
Compiler das Verhalten ändern
Gast #4494952
Lesenswert?

So sieht es aus:
1
Projekt: A                        Projekt: B
2
Verzeichnis: AV                   Verzeichnis: BV
3

4
Datei: hardware.h in AV           Datei: hardware.h in BV
5
       ...                               ...
6
       #define TxD PORTB0                #define TxD PORTC3
7
       ...                               ...
8

9
                     Datei: SoftSerial.c
10
                     Datei: SoftSerial.h
11
                     Verzeichnis: driver/
12

13

14
Datei: main.c in AV               Datei: main.c in BV
15

16
#include ?                        #include ?
17
#include "driver/SoftSerial.h"    #include "driver/SoftSerial.h"

Es soll von SoftSerial.c die hardware.h des Projekts A oder des Projekts 
B genommen werden.
Gast #4495008
Lesenswert?

GCCUser schrieb:
> Rolf Magnus schrieb:
> GCCUser schrieb:
> #include ?
>
> #include "hardware.h"
> Ggf dann über den include-Pfad das richtige Verzeichnis einbinden.
>
> Dann kennt die main.c die Definitionen. SoftSerial.c bekommt davon
> nichts mit.

Darauf hatte ich gar nicht geachtet. Das include muss natürlich nicht in 
main.c, sondern in SoftSerial.c.
Gast #4495027
Lesenswert?

Rolf Magnus schrieb:
> GCCUser schrieb:
>> Rolf Magnus schrieb:
>> GCCUser schrieb:
>> #include ?
>>
>> #include "hardware.h"
>> Ggf dann über den include-Pfad das richtige Verzeichnis einbinden.
>>
>> Dann kennt die main.c die Definitionen. SoftSerial.c bekommt davon
>> nichts mit.
>
> Darauf hatte ich gar nicht geachtet. Das include muss natürlich nicht in
> main.c, sondern in SoftSerial.c.

Wie man oben sehen kann gibt es zwei (min.) hardware.h. Es soll immer 
die hardware.h aus dem aktuellen Projekt genommen werden.
Gast #4495051
Lesenswert?

Du gibst beim Aufruf des Compilers mit "-I" die Verzeichnisse an, in 
denen nach include-Dateien gesucht wird. Das ist dann halt je nach 
Projekt unterschiedlich.

Du kannst auch, wie von Johann erwähnt, mit der Compileroption 
"-include" eine Datei in sämtliche Sourcen inkludieren. Das ist aber aus 
meiner Sicht die schlechtere Lösung, weil es dann eben überall 
inkludiert wird und nicht nur dort, wo man es braucht. Außerdem taucht 
der Name "hardware.h" dann nirgends es im Quelltext auf. Wenn sich das 
jemand anderes oder Du selber in ein paar Monaten wieder anschaut, geht 
erst mal die Sucherei los, was man denn alles zum Compilieren braucht 
...
Gast #4495101
Lesenswert?

Hans schrieb:

> Du gibst beim Aufruf des Compilers mit "-I" die Verzeichnisse an, in
> denen nach include-Dateien gesucht wird. Das ist dann halt je nach
> Projekt unterschiedlich.

Vielen Dank für diesen auf Projekte bezogen Vorschlag. Werde ich einfach 
einmal ausprobieren, wie das in der Praxis so wirkt.
#4496898
Lesenswert?

Übergebe dem Modul in seiner Init Funktion die  notwendigen 
Informationen (port register,  pin nummer, etc)


Oder was ich auch manchmal mache sind Callback-funktionen, entweder 
dynamisch zur Laufzeit oder statisch zur Compilezeit,  letzteres kann 
(und wird) von der LTO sogar geinlined werden, sogar über mehrere 
Aufrufebenen und mehrere Module hinweg.
Gast #4496930
Lesenswert?

> Außerdem taucht
> der Name "hardware.h" dann nirgends es im Quelltext auf. Wenn sich das
> jemand anderes oder Du selber in ein paar Monaten wieder anschaut, geht
> erst mal die Sucherei los,

  Die "Sucherei" beginnt ganz geordnet im projektspezifischen Makefile: 
hier drin stehen alle "Meta"-Angaben wie das Projekt zu bauen ist, also 
auch "-D", "k
-include" usw.
  Makefiles sind auch Bestandteil des Quellcodes.

  Wer auf nicht-klartext Projektbeschreibungen/Projektzusatzinfos 
verzichtet weil es $IDE ach-soooo-bequem über zig GUI-Dialoge/Reiter 
verstreut und über Versionen an anderen Orten verschiebt, verpasst 
einiges. Darunter:
* die vollständige Übersicht dieser Zusatzinfos zu seinem Projekt
* die "Versionierbarkeit" (oder wie schaut ein diff von 
XML-Projektdaten aus, wen die enthaltenen Elemente vllt. identisch, aber 
in anderer Ordnung drin stehen?)
Gast #4499452
Lesenswert?

I <3 makefiles schrieb:
>   Die "Sucherei" beginnt ganz geordnet im projektspezifischen Makefile:
> hier drin stehen alle "Meta"-Angaben wie das Projekt zu bauen ist, also
> auch "-D", "k
> -include" usw.
>   Makefiles sind auch Bestandteil des Quellcodes.

Allerdings sucht man (zumindest ich) in der Regel nicht unbedingt im 
Makefile nach inkludierten Headern - bzw. wundere mich, wenn z.B. beim 
Bauen eine C-Files ein Fehler in einem Header kommt, der auf den ersten 
Blick eigentlich gar nicht eingebunden ist.
#4499584
Lesenswert?

Es gibt noch ne halbwegs elegante Möglichkeit das Problem auf 
pragmatisch-simple Weise zu lösen, ich mach das zum Beispiel so bei 
meinen Projekten:

In jedem meiner Projekte existiert unter anderem immer (und das habe 
ich einfach mal so beschlossen und zum hausinternen Standard gemacht) 
ein "gpio.h", jedes andere Modul das irgendwas an der Hardware wackeln 
will kann und wird das includieren (und zwar ganz offiziell per 
#include, nicht hinten rum über die Kommandozeile) und kann davon 
ausgehen daß es auch tatsächlich existiert, in diesem gpio.h sind alle 
benutzten gpio-Pins mit sinnvollen Namen definiert, dort ist auch eine 
static inline gpio_init() Funktion die alle Pins und das pin-muxing 
initialisiert und und ebenso plaziere ich dort noch alle von der 
Pinbelegung abhängigen defines wie zum Beispiel benötigte 
ADC-Muxer-Kanäle, Timer-Kanäle, etc. mit sinnvollen Namen.

Da brauch ich also keine Verrenkungen machen oder gar heimliche includes 
im Makefile verstecken, ich lege stattdessen einfach fest und 
dokumentiere dementsprechend daß eine Datei "gpio.h" vorhanden sein muss 
dort dieses und jenes definiert sein muss. Punkt aus.

Das kann man auch sehen wenn man in den Code reinschaut, die wird da 
ganz hochoffiziell auf normalem Wege inkludiert, so daß man es sofort 
sehen kann. Wenn sie fehlt gibts aussagekräftige Fehlermeldungen, ebenso 
wenn ich vergessen habe dort irgendeinen benötigten Pin zu definieren.

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