bedingte Kompilierung, Makros

bedingte Compilierung

Wenn man erstmal so richtig am programmieren ist, möchte man sich z.B. verschiedene Sachen ausgeben lassen. Natürlich kommt da die serielle Schnittstelle ins Spiel. Also spickt man seinen Quelltext an den entsprechenden Stellen mit Serial.print Ausgaben. Sehr schön. So, fertig, alles läuft und jetzt? Jetzt müssen diese blöden Ausgaben natürlich auch wieder raus. Dann findet man wieder eine Fehler und muss das ganze Zeug wieder einbauen. 1. Möglichkeit ist natürlich alles immer ein und auszukommentieren. Aber auch das ist viel Arbeit. Wie gut, daß Arduino einen recht umfangreichen C-Compiler benutzt. Dieser beherscht bedingte Kompilierung. D.h. der Compiler kann anhand von sog. Compilerschaltern erkennen, ob er den Code, den er gerade vorsich hat, compilieren soll oder nicht. Schön und Gut aber wie hilft uns das jetzt? Naja, wir machen uns einen solchen Schalter selber und nennen den z.B. debug.

Definieren ist ganz einfach:

#define debug

Und Abfragen ist auch simple

#ifdef debug
...
#endif

Alles was zwischen den beiden Compiler Direktiven (so nennen sich die Dinger mit dem #) steht wird nur mit compiliert wenn auch der Schalter debug definiert wurde. Zum Ein und Ausschalten reicht es nun einfach den define ein bzw. auszukommentieren. Also #define debug schaltet alles ein, //#define debug schaltet alles aus.

Klasse. Gibt's auch 'ne Möglichkeit auf das nicht vorhandensein einer definition zu prüfen? Aber klar:

#ifndef debug
...
#else
...
#endif

Und hier sieht man auch, daß es auch bei diesen Direktiven einen else Zweig gibt. (Natürlich auch beim #ifdef). So können wir jetzt überall schreiben:

...
#ifdef debug
  Serial.begin(57600); 
#endif
...
#ifdef debug
    Serial.print(value, HEX);
#endif

Makros

Na, so haben wir den Quelltext schon mal leichter im Griff. Für's debuggen ist aber deutlich mehr Schreibarbeit. Kann man das evt. noch verkürzen? Ja auch das, jetzt wird's aber etwas tricky. Es bleibt bei dem #ifdef define. Wir fügen jetzt 2 sog. Makros zur Ausgabe hinzu. Ein Makro ist eine sog. Ersetzung. Überall wo der compiler das Makro findet wird es auch den Text ersetzt, den wir bei der Definition angegeben haben. Beispiel:

#define dbgOut(S) \
Serial.print(S); 

d.h. der Compiler ersetzt alle dbgOut mit dem Parameter S durch Serial.print(S); Man kann natürlich auch das Makro leer lassen, dann würde der Compiler den Befehl entfernen.

#define dbgOut(S)

Na bitte, jetzt kombinieren wir das noch mit der bedingten Compilierung und schon haben wir eine recht einfache Möglichkeit, debug Ausgaben ein bzw. auszuschalten.

#ifdef debug
#define dbgOut(S) \
Serial.print(S); 
#define dbgOutLn(S) \
Serial.println(S); 
#else
#define dbgOut(S)
#define dbgOutLn(S)
#endif

Ich habe noch ein zweites Makro für Serail.println() hinzugefügt. Will man jetzt im Programm was ausgeben, reicht ein einfaches dbgOut(„Wir sind hier“);

weiteres Beispiel

Wie wir noch später sehen werden, können wir mit dem Arduino auch Programme für andere Controller erzeugen. Beispielsweise für den ATTiny85. Das ist der kleine Bruder vom ATMega. Besitzt nur ein DIP8 Gehäuse und hat nur 5 Leitungen zur freien Verfügung. ber für kleinere Sachen reicht das ja völlig. Problem:

Ich würde gerne das Programm am Arduino testen und entwicklen und dann erst später für den ATTiny kompilieren und brennen. Nix einfacher als das, denn die IDE stellt bereits fertige Definitionen zur Verfügung.

Hat man z.B. als Target den ATTiny85 aktiv, wird automatisch ein #define __AVR_ATtinyX5__ aktiv.
d.h. man kann z.B. mit

// Hardwareanbindung 
#ifndef __AVR_ATtinyX5__ 
// Arduino Hardware
const byte Dout_0 = 4; 
const byte Dout_1 = 5;
const byte Dout_2 = 6;
const byte Dout_3 = 7;
#else
// ATTiny85 Hardware
const byte Dout_0 = 0; 
const byte Dout_1 = 1;
const byte Dout_2 = 2;
const byte Dout_3 = 3;
#endif

die komplette Hardwaredefinition automatisch umschalten. Und man kann natürlich das ganze auch wieder komplett verschalchteln. Was macht wohl das hier:

#ifndef __AVR_ATtinyX5__ 
#ifdef debug
  Serial.begin(57600); 
  Serial.flush();
#endif
#endif
arduino/tutorial/sprechen-sie-arduino/mehr-bitte/bedingte-kompilierung-makros.txt · Zuletzt geändert: 2018/11/04 10:51 von 127.0.0.1
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0