Auf Kommando

In der letzten Ausgabe des Blogs war von IDEs für die Softwareentwicklung unter Arduino die Rede. In diesem Posting geht es um die Welt der Kommandozeilen-Werkzeuge.

In Pocket speichern vorlesen Druckansicht 2 Kommentare lesen
Lesezeit: 10 Min.
Von
  • Dr. Michael Stal
Inhaltsverzeichnis

In der letzten Ausgabe des Blogs war von IDEs für die Softwareentwicklung unter Arduino die Rede. In diesem Posting geht es um die Welt der Kommandozeilen-Werkzeuge.

Um es gleich vorwegzunehmen: Früher galten die Nutzer grafischer Entwicklungsumgebungen als verweichlichte Entwickler, die sich die Hände nicht schmutzig machen wollen, während echte Profis selbstredend Kommandozeilen-Tools nutzten. Heute ist es eher eine Sache des persönlichen Geschmacks und der eigenen Vorlieben, welcher Weg der richtige ist.

Komfort und Funktionsumfang einer professionellen IDE sprechen für sich. Auf der anderen Seite gibt es Situationen, bei denen Entwickler zum Beispiel dem Übersetzer oder dem Flash-Tool Optionen mitgeben wollen, wobei sie in einer IDE umständlich an den Einstellungen hantieren müssen. Kommandozeilen-gestählte Entwickler schwören auf die Mächtigkeit ihrer Editoren und die schnellere Turnaround-Zeit beim Entwickeln.

Es mag auf den ersten Blick verwirrend erscheinen, aber der erste Schritt zum Verwenden der Kommandozeile für die Arduino-Programmierung besteht in der Installation der Arduino IDE.

Die Arduino IDE bringt alle für die Kommandozeile benötigten Werkzeuge schon mit: den Compiler, das Tool zum Flashen des Boards, Linker, Archiver, und vieles mehr.

Doch wo genau finden sich diese Werkzeuge auf Ihrem System?

  • Unter macOS ist es das Verzeichnis /Applications/Arduino.app/Contents/Java
  • Unter Windows: <HAUPTLAUFWERK>:\Program Files (x86)\Arduino
  • Unter Linux: /usr/share/arduino

Zunächst stellt sich natürlich die Frage, mit welchen Werkzeugen wir es konkret zu tun haben. Hier eine unvollständige Liste zur Übersicht.

  • avr-gcc und avr-g++: Der GNU C++-Compiler ist das Herz der von AVR bereitgestellten Tools. Eine gute Anleitung finden Sie hier.
    • avr-objcopy: Dieses Programm bewegt Objektdateien und transformiert sie in ein anderes Zielformat.
    • avr-objdump gibt Informationen über das Objektfile aus.
    • avr-size liefert die Größen der Objektdateien beziehungsweise deren Daten-, Code-, ... Segmente zurück.
    • avr-nm zeigt die in einer Objektdatei enthaltenen Symbole.
    • ...
  • avrdude dient zum Downloaden von Code und Daten auf Microcontroller von AVR. Als Programmer fungieren laut manpage "Atmel’s STK500 Programmer, Atmel’s AVRISP, AVRISP mkII Programmer, Atmel’s JTAG ICE (mkI und mkII, letzterer auch im ISP Modus), Programmer Hardware kompatibel mit AppNote AVR910 und AVR109 (inklusive Butterfly), sowie alle einfachen festverdrahteten Programmer mit Direktverbindung zu einem ppi oder parport, Parallel Port, oder zu einem Standard Seriellen Port. Avrdude kann EEPROM und Flash ROM Speicher der unterstützten AVR-Komponenten bespielen, sowie Fuse Bits und Lock Bits konfigurieren".

Würden Entwickler diese Werkzeuge nun direkt und manuell aus der Kommandozeile heraus aufrufen, hätten sie nach kurzer Zeit keinen Spaß mehr am Programmieren. Zu vielfältig sind die Werkzeuge, Optionen und Parameter. Was nun?

Natürlich lautet die Antwort auf die Frage aller Fragen im Arduino-Maker-Universum make & Makefile. Nur woher nehmen und nicht stehlen? Mein Kollege Chris Drexler gehört zu den Kommandozeilen-Ninjas und empfiehlt Arduino-Makefile. Bei diesem Projekt (siehe Github-Verzeichnis von Arduino-Makefile) haben etliche "Aktivisten" ein umfangreiches und sehr flexibles Makefile geschaffen. Ähnliches selbst auf die Beine zu stellen, dürfte daher so ziemlich das letzte sein, wofür Sie Ihre Zeit investieren sollten. Nur einmal als Referenz: das Makefile Arduino.mk ist rund 60 KBytes (!) groß.

Arduino-Makefile ist über GitHub verfügbar

Voraussetzung für das Verwenden von Arduino-Makefile sind zwei Dinge:

  • Die Installation der Arduino IDE, wie bereits eingangs erwähnt.
  • Die Installation von python und der pySerial-Bibliothek (für den Zugriff auf serielle Ports).
readme.md

Sie erhalten das Makefile jedenfalls auf drei Arten:

  1. Durch Paketinstallation wie in der besagten Datei readme.md beschrieben, oder,
  2. durch Checkout aus GitHub: git clone https://github.com/sudar/Arduino-Makefile.git oder,
  3. durch Herunterladen der .ZIP-Datei von der Webseite https://github.com/sudar/Arduino-Makefile.

Nun könnten Entwickler für jeden individuellen Sketch das gigantische Makefile kopieren und entsprechend anpassen. Das wäre allerdings auf Dauer müßig. Stattdessen empfiehlt es sich, das zentrale Arduino.mk im Verzeichnis /Arduino-Makefile auf die eigene Umgebung zu adaptieren, und es dann in kleineren Sketch-spezifischen Makefiles zu inkludieren.

Dazu spezifizieren Sie zunächst die Umgebungsvariablen. In Windows enthält zum Beispiel das Menü Control Panel bzw. Einstellungen einen Dialog, um die Variablen hinzuzufügen.

Auf macOS oder Linux unter Nutzung von bash empfiehlt sich die Einrichtung/Ergänzung der Datei .bashrc. Beispielsweise lauten die notwendigen Zeilen auf meinem macOS-System:

export ARDUINO_DIR=/Applications/Arduino.app/Contents/Java
export ARDMK_DIR=/Users/Michael/Arduino-Makefile/
export AVR_TOOLS_DIR=/Applications/Arduino.app/Contents/Java/hardware/tools/avr/

Alternativ definieren Sie diese Variablen in Arduino.mk.

Zum Test sollten Sie ein Konsolen/Terminal-Fenster öffnen, im Ordner Arduino-Makefile beispielsweise zum Unterverzeichnis examples/Fade wechseln, und make aufrufen. Falls das ohne Fehlermeldungen funktioniert, ist der erste Schritt erledigt.

Diese Variablen sind unabhängig vom jeweiligen Sketch.

Zusätzlich gibt es noch spezielle Einstellungen für den Sketch.

Im Verzeichnis des Sketches genügt in der Regel ein Makefile mit Sketch-spezifischen Einstellungen. Dieses Makefile importiert Arduino.mk mit dessen globalen Regeln. Meistens besteht ein Makefile für den Sketch nur noch aus ein paar Zeilen.

Für das bereits genannte Fade-Beispiel würde zum Beispiel der Inhalt eines Makefiles wie folgt aussehen, wenn wir von einem Leonardo-Board ausgehen. Der angegebene Port ist der in meiner Umgebung benutzte USB-Port:

BOARD_TAG = leonardo
ARDUINO_PORT = /dev/cu.usbmodem14311

include $(ARDMK_DIR)/Arduino.mk


BOARD_TAG definiert das konkret verwendete Arduino-Board.

ARDUINO_PORT spezifiziert den verwendeten USB-Port.

In der include-Anweisung importieren wir das eigentliche Makefile Arduino.mk.

Nachdem nun alle Vorbereitungen getroffen sind, kann das eigentliche Verwenden von make erfolgen. Es gibt hierfür zahlreiche Optionen. Aus Platzgründen kommen in diesem Kapitel die in der Praxis wichtigsten zur Sprache.

  • make show_boards gibt die Liste der unterstützten Boards aus:

Ausgabe der unterstützten Boards über make show_boards
  • Mittels Aufruf von make erfolgt die Erzeugung des ausführbaren Sketches:

Erzeugen des binären Sketches mit make
  • make upload sorgt mittels avrdude für Upload des lauffähigen Sketches auf das Leonardo-Board:

make upload flasht den Sketch auf das Board
  • Bei Aufruf von make monitor sehen wir die serielle Kommunikation zwischen Computer und Arduino-Board wie hier beim Blink-Programm:

Serielle Kommunikation nach Aufruf von make monitor

Das Makefile versucht, selbständig die benötigte Baudrate des seriellen Monitors einzustellen. Sollte dies fehlschlagen, gibt es die Möglichkeit, über eine Variable den entsprechenden Wert zu spezifizieren, z.B.:

     MONITOR_BAUDRATE = 19200

Auch diese Variable gehört in das Makefile des jeweiligen Sketches.

  • Wenn Sie übrigens nähere Information über weitere Verwendungen des Makefile benötigen, genügt ein Aufruf von make help:

Available targets:
make
- compile the code
make upload - upload
make ispload - upload using an ISP
make raw_upload - upload without first resetting
make eeprom - upload the eep file
make raw_eeprom - upload the eep file without first resetting
make clean - remove all our dependencies
make depends - update dependencies
make reset - reset the Arduino by tickling DTR or changing baud
rate on the serial port.
make show_boards - list all the boards defined in boards.txt
make show_submenu - list all board submenus defined in boards.txt
make monitor - connect to the Arduino's serial port
make size - show the size of the compiled output (relative to
resources, if you have a patched avr-size).
make verify_size - verify that the size of the final file is less than
the capacity of the micro controller.
make symbol_sizes - generate a .sym file containing symbols and their
sizes.
make disasm - generate a .lss file that contains disassembly
of the compiled file interspersed with your
original source code.
make generate_assembly - generate a .s file containing the compiler
generated assembly of the main sketch.
make burn_bootloader - burn bootloader and fuses
make set_fuses - set fuses without burning bootloader
make help_vars - print all variables that can be overridden
make help - show this help

Sollten Sie Bibliotheken verwenden, teilen Sie diese in Ihrem Sketch-Makefile über ARDUINO_LIBS mit.

Im Beispiel

     ARDUINO_LIBS = Ethernet SPI LiquidCrystal

finden demzufolge die Bibliotheken Ethernet, SPI und LiquidCrystal Verwendung.

Das Beispiel BlinkInAVRC (siehe examples-Verzeichnis von $ARDMK_DIR) enthält folgendes C-Programm, das zum unausweichlichem LED-Blinken im Halbsekundentakt dient.

#include <avr/io.h>
#include <util/delay.h>

void init_io(void)
{
// 1 = output, 0 = input
DDRB = 0b11111111; // All outputs
DDRC = 0b11111111; // All outputs
DDRD = 0b11111110; // PORTD (RX on PD0). Just for demo
}

int main(void)
{
init_io();

while (1)
{
PORTC = 0xFF;
PORTB = 0xFF;
PORTD = 0xFF;
_delay_ms(500);

PORTC = 0x00;
PORTB = 0x00;
PORTD = 0x00;
_delay_ms(500);
}

return 0;
}

Das Beispielsverzeichnis liefert dazu folgendes Makefile:

NO_CORE = Yes

BOARD_TAG = atmega16
MCU = atmega16
F_CPU = 8000000L

ISP_PROG = stk500v1
AVRDUDE_ISP_BAUDRATE = 19200

include ../../Arduino.mk

Da das Programm über einen ISP-Programmer auf das Board geflasht werden muss, rufen Sie zu diesem Zweck

make ispload

auf, das dies mit 19200 Baud erledigt. Laut Definition von ISP_PROG handelt es sich um eine ISP-Programmer-Hardware mit stk500v1-Unterstützung, was auch sehr viele preisgünstige Programmer beherrschen.

Falls Sie noch mehr Hintergrundinformationen erfahren wollen. Der Autor des Arduino-Makefile gibt in einem Beitrag einen guten Überblick über dessen vielfältigen Möglichkeiten. Zum Beispiel finden Sie dort eine Beschreibung der Integration des beliebten Editors vim mit dem Arduino-Makefile.

In diesem und im letzten Blog haben wir Ausflüge zur Welt der Softwareerstellung für Arduino-Projekte unternommen. Dabei ging es zum einen um alternative Entwicklungsumgebungen anstelle der Arduino IDE, und zum anderen um das Verwenden von Kommandozeilen-Werkzeugen. Das Arduino-Ökosystem bietet etliche Optionen, sodass sich für jeden Geschmack und für unterschiedliche Bedürfnisse zumindest eine brauchbare Lösung finden lässt.

Die nächsten Posts beschäftigen sich wieder mit konkreten Projekten und nützlichen Hardwarekomponenten. ()