Quickstart Linux
Worum geht's?
[Bearbeiten]Eine erste Hürde beim Einstieg in die Programmierung von Microcontrollern, auch für erfahrene C-Programmierer, stellt der Umgang mit den für die Entwicklung eingesetzten Werkzeugen dar.
Ziel dieses Kapitels ist es Dich so schnell wie möglich zum ersten lauffähigen Programm zu bringen. Das Augenmerk wird dabei noch nicht darauf liegen, ein möglichst elegantes Buildsystem zu entwerfen, sondern Dich "Quick and Dirty" an einen Punkt zu bringen, von dem an Du eigenständig Programme auf Deinem Microcontroller zum laufen bringen kannst.
Die nötigen Schritte werden in diesem Kapitel ausschließlich von Hand vorgenommen werden. Möglichkeiten zur Automatisierung und Erarbeitung eines komfortableren Buildsystems werden in einem späteren Kapitel folgen.
In diesem Kapitel kannst die die folgenden Dinge lernen:
- Die benötigte Software Software herunterladen und installieren
- Datenblätter herunterladen
- Zugriffsrechte auf die serielle Schnittstelle konfigurieren
- Quellcode Dateien zu übersetzen und zu linken
- Fertig übersetzte Programme auf den Arduino übertragen
Software herunterladen und installieren
[Bearbeiten]Um C-Programme für AVR Microcontroller zu übersetzen werden ein C-Compiler und eine Implementierung der C-Standarbibliothek benötigt.
Sowohl die in diesem Buch verwendete Compiler Suite avr-gcc, als auch die C Bibliothek AVR Libc kommen aus dem GNU Projekt. Viele Distributionen stellen beide Komponenten bereits über die Paketverwaltung zur Verfügung. Häufig jedoch in veralteter Version.
Aus diesem Grund wird an dieser Stelle ein alternativer Weg beschritten. Beide Komponenten sind in aktueller Version in der Arduino-IDE Entwicklungsumgebung enthalten.
Herunterladen
[Bearbeiten]Die aktuelle Version 1.8.0 der Arduino-IDE (enthält gcc Version 4.9.2 / avr-libc Version 2.0.0) kann von der zugehörigen Website heruntergeladen werden. Dort einfach die gewünschte Variante 32-bit bzw. 64-bit auswählen.
Entpacken
[Bearbeiten]Je nachdem, ob die 32-bit oder die 64-bit Variante heruntergeladen wurde, kann das Archiv mit einem der folgenden Kommandos entpackt werden:
xzcat arduino-1.8.0-linux32.tar.xz | tar xv xzcat arduino-1.8.0-linux64.tar.xz | tar xv
Nach dem Entpacken befindet sich der Inhalt des Archivs im neu entstandenen Unterverzeichnis arduino-1.8.0. Die benötigten Werkzeuge liegen gut versteckt im Unterverzeichnis arduino-1.8.0/hardware/tools/avr.
Um die Beispielprogramme dieses Buchs zu übersetzen genügt der Inhalt dieses Verzeichnisses.
Da die überflüssigen Teile der Arduino-IDE nicht sehr viel Platz benötigen, habe ich auf meinem System das vollständige Unterverzeichnis arduino-1.8.0 in das Verzeichnis /opt kopiert. Wenn Du der Beschreibung folgen willst, kannst Du den selben Schritt mit folgendem Befehl durchführen.
Vorsicht! Alle Befehle, die mit Superuser Rechten ausgeführt werden, können erheblichen Schaden anrichten.
Deshalb vor dem Abfeuern am besten noch einmal doppelt kontrollieren, dass auch nichts vertippt ist.sudo cp -r arduino-1.8.0 /opt
Datenblatt herunterladen
[Bearbeiten]Ein wichtiger Schritt, den Du an dieser Stelle unbedingt unternehmen solltest, ist Dir das entsprechende Datenblatt für Deinen Microcontroller herunterzuladen. Datenblätter findest Du auf der Atmel Homepage.
Unternimm diesen Schritt bitte unbedingt. Ohne die zugehörige Referenz wirst Du nur sehr wenig mit Deinem Microcontroller anfangen können. Zugegeben die Lektüre von Datenblättern ist eher trocken und nicht so spannend wie die eines Kriminalromans oder eines Thrillers. Dafür wird es später aber umso weniger Überraschungen geben. Anders als in einem packenden Thriller markieren sie bei der Programmierung nicht den Höhepunkt, sondern wirken sich eher nervig aus.
Quellcode übersetzen
[Bearbeiten]In diesem Abschnitt soll es darum gehen, ein erstes Programm für den Microcontroller zu übersetzen.
Zu diesem Zeitpunkt ist es noch nicht wichtig, jede Zeile des Quellcodes genau zu verstehen. Es geht vielmehr darum, den Umgang mit den Werkzeugen zu erlernen und sicherzustellen, dass alles korrekt installiert ist.
Den Quellcode des Programms findest Du hier:
#include <avr/io.h>
#include <util/delay.h>
// Forward Declarations
void setup(void);
void loop(void);
#define BLINK_DELAY_MS 500
void setup()
{
sbi(DDRB, DDB5); // LED: PORTB5 out
}
void loop()
{
sbi(PINB, PINB5); // toggle LED
_delay_ms(BLINK_DELAY_MS); // delay
}
#ifndef ARDUINO
int main(void)
{
setup();
while(1)
loop();
}
#endif
Um ihn in ein fertiges Programm umzuwandeln, müssen mehrere Schritte unternommen werden.
Damit die frisch installierten Werkzeuge auch ohne Angabe des kompletten Pfads gefunden werden, muss zunächst der Suchpfad entsprechend angepasst werden. Wenn Du dem Vorschlag gefolgt bist, die heruntergeladene Arduino-IDE vollständig nach /opt zu kopieren, kann dafür der folgende Befehl verwendet werden:
export PATH=/opt/arduino-1.8.0/hardware/tools/avr/bin:$PATH
Objektfile erstellen
[Bearbeiten]Jede Quelle muss in eine Objektdatei übersetzt werden. Zu diesem Zweck muss der Compiler mit der Option -c aufgerufen werden.
avr-gcc -c CPPFLAGS CFLAGS source.c
Noch spuckt der Compiler eine ganze Reihe Fehlermeldungen aus, um die wir uns im Folgenden kümmern werden.
Wenn der CPU-Typ nicht angegeben ist, meldet der Compiler folgendes Problem:
warning: #warning "device type not defined"
Der CPU-Typ kann mit der Option -mmcu=«CPU»angegeben werden. Anstelle von «CPU» muss der CPU-Typ angegeben werden. Für einen AtMega328p ist beispielsweise -mmcu=atmega328p anzugeben. Eine Übersicht über die Namen findet man z.B. in der Dokumentation der AVR Libc.[1]
Da die Geschwindigkeit der CPU nicht angegeben wurde, meldet der Compiler nun folgendes Problem:
warning: #warning "F_CPU not defined for <util/delay.h>"
Um die Geschwindigkeit anzugeben, muss das Präprozessormakro F_CPU definiert werden und den Takt angeben. Mit dem Schalter -D«name»=«wert» kann dem C-Präprozessor die Definition zusätzlicher Makros übergeben werden, für einen Arduino Duamillenova beispielsweise -DF_CPU=16000000UL.
Die letzte Warnung resultiert daraus, dass wir den Code ohne Optimierung übersetzt haben.
warning: # warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
Damit die Zeitmessung richtig funktioniert, muss die Optimierung eingeschaltet sein. Um auch die letzte Warnung loszuwerden, muss die Option -Os übergeben werden.
In der endgültigen Version sieht der Befehl für das Kompilieren also wie folgt aus:
avr-gcc -c -Os -mmcu=atmega328p -DF_CPU=16000000UL source.c
Nach erfolgreichem Übersetzen der Quelle gibt es nun die Datei source.o.
Objektfiles linken
[Bearbeiten]Um das Programm lauffähig zu machen, müssen Objektdateien, verwendete Bibliotheken und Startcode zu einem Programm zusammengeführt (gebunden / gelinkt) werden.
In unserem Fall liegt nur eine Objektdatei vor.
avr-gcc -mmcu=atmega328p source.o
Der Standardname des generierten Programms ist a.out. Um einen anderen Namen vorzugeben, kann der Schalter -o verwendet werden. Da das erstellte Programm im ELF (executable and link format) Format vorliegt, werden wir ihm als Gedächtnisstütze die Erweiterung .elf geben.
In der endgültigen Version sieht der Befehl für das Linken also wie folgt aus:
avr-gcc -mmcu=atmega328p -o source.elf source.o
Programm konvertieren
[Bearbeiten]Um das Programm auf dem Microcontroller installieren zu können, müssen wir es zunächst in ein geeignetes Format umwandeln. In unserem Fall soll es mit avrdude in den Flash-Speicher geschrieben werden. Mit der folgenden Befehlszeile kann es in ein für avrdude brauchbares Format umgewandelt werden.
avr-objcopy -O ihex -R .eeprom source.elf source.hex
Zugriffsrechte serielle Schnittstelle
[Bearbeiten]Damit das fertig übersetzte Programm auf den Microcontroller übertragen werden kann, ist es erforderlich dass Dir das Betriebssystem Zugriff auf die serielle Schnittstelle erlaubt. Um das zu bewerkstelligen ist es wichtig die zugehörige Gerätedatei und deren Besitzer herauszufinden.
Schließe das Board an den PC an. Üblicher Weise sollte der Name der Gerätedatei /dev/ttyUSB0 heißen. In diesem Fall kannst Du den Besitzer mit folgendem Befehl ermitteln.
ls -l /dev/ttyUSB0
Die Ausgabe sollte so aussehen:
crw-rw---- 1 root dialout 188, 0 Jan 5 14:32 /dev/ttyUSB0
Interessant für das weitere Vorgehen ist der Name der zugehörigen Gruppe. Im angeführten Beispiel ist dies der Name dialout. Je nach eingesetzter Linux Distribution kann dort auch der Name tty stehen.
Um Zugriff auf die Gerätedatei und damit auf die serielle Schnittstelle zu erhalten, musst Du den Benutzeraccount, mit dem Du arbeitest zu der ermittelten Gruppe hinzufügen. Für die Gruppe dialout aus dem Beispiel kann dafür der folgende Befehl eingegeben werden. Bei einem anderen Gruppennamen brauchst Du lediglich dialout durch den ermittelten Gruppennamen ersetzen.
Vorsicht! Auch dieser Befehl muss mit Superuser Rechten ausgeführt werden. Es gelten die selben Vorsichtsmaßnahmen wie zu zuvor!
Auch hier besser einmal zu viel kontrollieren, ob alles richtig getippt ist, als einmal zu wenig.sudo usermod -a -G dialout ${USER}
Programm installieren
[Bearbeiten]Mit dem Programm avrdude kann das Programm installiert werden.
Mit dem Parameter -C muss der Pfad zu einer gültigen Konfigurationsdatei übergeben werden. Wenn Du dem Vorschlag gefolgt bist die heruntergeladene Arduino-IDE vollständig nach /opt zu kopieren, kannst Du den Pfad so verwenden, wie er im folgenden Befehl angegeben ist. Andernfalls muss er entsprechend angepasst werden.
Der Parameter -P gibt den Pfad der Gerätedatei der seriellen Schnittstelle an, den Du bereits im Abschnitt serielle Schnittstelle bestimmt hast. Sollte er von /dev/ttyUSB0 abweichen, musst Du auch diesen Parameter anpassen.
avrdude -vvv -C /opt/arduino-1.8.0/hardware/tools/avr/etc/avrdude.conf -p atmega328p -c stk500v1 -P /dev/ttyUSB0 -b 57600 -D -U flash:w:source.hex
Nach dem Hochladen des Programms sollte die Leutdiode L in regelmäßigem Rhythmus blinken.
Rückblick und Ausblick
[Bearbeiten]Glückwunsch Du hast Dein erstes Programm erfolgreich zum laufen gebracht!
In diesem Kapitel hast Du eine funktionierende Entwicklungsumgebung geschaffen, mit der Du experimentieren kannst. Du hast:
- Mit avr-gcc und der AVR Libc hast Du C-Compiler und C-Standardbibliothek installiert
- Dir die nötigen Zugriffsrechte verschafft um auf die serielle Schnittstelle zugreifen zu können.
Darüber hinaus hast Du bereits erfolgreich Dein erstes Programm übersetzt und zum laufen gebracht. Dabei hast Du im einzelnen:
- Eine C-Quellcode Datei übersetzt und daraus eine Objektdatei erzeugt
- Die Objektdatei zu einem fertigen Programm im ELF Format gelinkt
- Das ELF Programm in ein für avrdude taugliches Format konvertiert.
- Das Programm auf den Arduino übertragen.
Bisher wurden alle Operationen von Hand vorgenommen. Im folgenden Kapitel wird eine Methode vorgestellt, mit der Aufgaben wie diese automatisiert werden können.
Fußnoten
[Bearbeiten]- ↑ siehe: Abschnitt "Supported Devices" unter http://www.nongnu.org/avr-libc/user-manual/index.html