www.mikrocontroller.net

Forum: GCC Bedingte Kompilierung

Autor: ALex (Gast)
Datum: 05.05.2008 11:39

Hi,

ich arbeite mit AVR Studio und möchte abhänging vom Device meinen
Quellcode compilieren. Dazu möchte ich "MCU" auswerten und zwischen
ATMEGA und ATTINY unterscheiden.

Meine Frage: gibt es eine möglichkeit, bei #if bzw. #ifdef usw. zu
schauen, ob in "MCU" ATTINY oder ATMEGA steht und den Rest (bei ATMEGA
32,16,8 usw.) auszublenden, durch Wildcards oder ähnlich??

Gruß, Alex
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum: 05.05.2008 13:04

Nein, wildcards gibt es nicht.  Du musst schon einzeln testen:
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__)
#  define THIS megaTHIS
#elif defined(__AVR_ATtiny13__) || defined(__AVR_ATtiny261__)
#  define THIS tinyTHIS
#else
#  error "Unknown MCU type"
#endif
Autor: mikro_sven (Gast)
Datum: 05.05.2008 22:26

Hallo,

da häng ich mich doch gleich mit dran, wenn so ein Thema schonmal offen
ist:

Ich habe ein ähnliches Problem, ich will eine Initialisierung meines
verwendeten Controllers vornehmen. Dazu will ich über eine Art
"Case-Struktur" entscheiden, welcher Controller gewählt wurde und nur
den dafür zutreffenden Code compilieren lassen. Die restlichen Cases
brauch ich aber ja nicht im Code, würde nur Platz verschwenden.

Nun dachte ich an eine Bibliothek, die ich dann ins eigentliche Programm
einbinde. Im Hauptprogramm wird dann beispielsweise über
#define mcu tiny25
der Controller festgelegt. In der Bibliothek würde ich dann - wie oben
beschrieben - über ifdefs den linker entscheiden lassen, welchen
Init-Code er compiliert. Aber das kann doch unglaublich umfangreich
werden, oder nicht?

Jetzt hab ich aber mit C leider noch nicht allzu große Erfahrung und
frage mich, ob das überhaupt Funktioniert bzw. guter Stil ist, oder ob
man besser anders vorgeht. Könnte man das ganze auch über ein Makefile
lösen und wenn, wie sollte man da am Besten vorgehen? Ich habe schon
einige Beispiele über Makefiles gelesen (u. a. auch den Exkurs im
GCC-Tutorial), aber bedingte Compilierungen hab ich da nicht gefunden.

Viele Grüße und Danke für eure Vorschläge!

Sven
Autor: Martin Thomas (mthomas) Benutzerseite
Datum: 05.05.2008 23:09

Könnte man im Makefile nach WinAVR-Vorlage so lösen:

# fuer alle controller
SRC=wieauchimmer.c egal.c foo.c
# controllerspezifischer code
ifeq($(MCU),atmega128)
SRC+=codefueratmega128.c
endif
ifeq($(MCU),atmega16)
SRC+=codefueratmega16.c
endif

Vgl. z.B. http://www.siwawi.arubi.uni-kl.de/avr_projects/#avrprog_boot

Ob das nun übersichtlicher ist, als den Preprocessor zu bemühen, mag
jeder selbst entscheiden. Meist sind die Unterschiede nicht so gross,
dass eigene Quellcodedateien benötigt werden.
Autor: Rufus t. Firefly (rufus) (Moderator)
Datum: 06.05.2008 09:14

> In der Bibliothek würde ich dann - wie oben beschrieben -
> über ifdefs den linker entscheiden lassen, welchen
> Init-Code er compiliert.

Das geht so nicht. Präprozessoranweisungen wie #ifdef werden vom
Präprozessor ausgewertet, und dessen Resultat landet im Compiler. Der
Linker bekommt Präprozessoranweisungen nie zu sehen.

Dein Ansatz kann -leicht abgewandelt- dennoch funktionieren:
Den Prozessorspezifischen Code packst Du in eigene Module (mindestens
eines pro Prozessor) und die darin enthaltenen Funktionen benennst Du
entsprechend eindeutig, also beispielsweise

  m128_init in m128.c
  m32_init in m32.c
  m16_init in m16.c

etc.

Die alle übersetzt Du und packst sie in eine Library. Etwaig verwendete
globale Variablen müssen ebenfalls dieser Nomenklatur gehorchen.

Dein diese Library nutzender Code bindet eine Headerdatei ein, in der
per Präprozessoranweisungen aus dem generischen "init" der jeweils zu
verwendende Name erzeugt wird:

  #if defined(_AVR_ATmega16_)
  #define init m16_init
  #endif

  #if defined(_AVR_ATmega128_)
  #define init m128_init
  #endif

Dein Code ruft "init" auf; durch die Präprozessoranweisung wird das
korrekte implementierungsabhängige "init" daraus gemacht und der Linker
linkt aus der Library das Modul, in dem der zugehörige Code enthalten
ist.

So ginge es.
Autor: Georg-johann L. (sprintersb)
Datum: 06.05.2008 09:24

Vielleicht hilft Dir das builtin Define _ARV_ARCH_ ?


http://www.roboternetz.de/wissen/index.php/Avr-gcc...
Autor: mikro_sven (Gast)
Datum: 09.05.2008 10:19

Danke für eure Antworten!

@rufus: Gute Idee! Zum testen habe ich mir die entsprechenden Module und
die Library erstellt. Das Header-File (msp_init.h) sieht nun so aus:
int msp430_1_init(void);
int msp430_2_init(void);
int msp430_3_init(void);

#if defined(_MSP430_1_)
#define init msp430_1_init
#endif

#if defined(_MSP_430_2_)
#define init msp430_2_init
#endif

#if defined(_MSP_430_3_)
#define init msp430_3_init
#endif

Meine Main hab ich so geschrieben:
#include "msp_init.h"
#define MSP430_1

int main(void)
{
  init();
}

Nun bekomme ich leider einen Fehler, dass "init" nicht definiert ist.
Verstehe ich das richtig, dass der Präprozessor im Header-File bei den
Präprozessoranweisungen in meinem Fall 'init' mit 'msp430_1_init'
ersetzt, da ich in der Main ja gesagt habe '#define MSP430_1'? Dann
würde im Code ja statt der Funktionsaufruf 'init();' der Aufruf
'msp430_1_init();' erfolgen.

Ich komm da grad nicht drauf...

Viele Grüße
Sven
Autor: Oliver (Gast)
Datum: 09.05.2008 12:17

#include "msp_init.h"
#define MSP430_1

ist wohl die falsche Reihenfolge.

Generell wäre es auch sinnvoll, ein #if...#elif..#else error "no device
defined"-Konstrukt zu verwenden, dann bekommst du eine aussagekräftige
Fehlermeldung.

Oliver
Autor: mikro_sven (Gast)
Datum: 09.05.2008 12:44

Perfekt! Danke, das war's. Warum sieht man solche Kleinigkeiten alleine
nur so schwer?!

Nur zur Info: Zusätzlich muss ich in der Main ja überhaupt
#define _MSP430_1_

statt
#define MSP430_1

schreiben ;-)

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net