Embedded Linux Image mittels Yocto erstellen
Am Beispiel eines kleinen DIY Projektes erläutere ich wie man mit Hilfe von Yocto ein Linux Image für einen Raspberry Pi kompeliert und von einen Linux Host mit GCC cross compilen kann.
Vor einiger Zeit habe ich aus einem billigen LCD und zugehörigen Controller Board von eBay, und einem Raspberry Pi einen digitalen Bilderrahmen gewerkelt. Auf einer 16 GB SD Card lief damals noch Raspberry Pi OS und über eine mit Electron entwickelte Anwendung wurden dann die Bilder auf den Display gezaubert. Zudem stellte die Anwendung einen kleinen REST Service zur Verfügung mit dem man Einstellungen ändern und die Bilder verwalten konnte. Als UI diente eine kleine React Webanwendung. Von der Performance her gab es überraschenderweise wenig zu beanstanden. Allerdings schrumpfte mit jedem Update der Speicherplatz nach und nach und am Ende waren nicht mehr als 4 GB frei. Anstatt eine größere SD Card zu kaufen entschied ich mich dafür das ganze in C++ neu zuschreiben und auf ein Linux Image, das auf das Nötigste reduzierte ist.
Worum geht es?
In diesem Beitrag geht es erstmal nur darum ein Linux Image zu kompelieren, es auf eine SD Card zu kopieren und von dieser dann einen Raspberry Pi booten zu lassen. Darüber hinaus werde ich erklären wie man die Entwicklerumgebung Qt Creator für das direkte Erstellen von Programmen für die ARM Architektur konfigurieren muss.
Vorbereitung
Auf meinem Rechner läuft Debian Buster und alle Schritte sollten auf jedem Debian basierten System ohne größere Komplikationen auch so funktionieren.
Als erstes müssen wir einige Pakete von denen Yocto abhängt installieren.
~$ sudo apt install install gawk curl git-core git-lfs \
diffstat unzip texinfo build-essential chrpath libsdl1.2-dev \
xterm gperf bison gcc-multilib g++-multilib repo
Yocto einrichten
Ich möchte mit Qt 5 in C++ die eigentliche Anwendung entwickeln. Daher muss das Linux Image auch die Qt 5 Librarys enthalten. Dafür greifen wir auf einen Yocto Layer von Qt zurück, der es ermöglicht direkt nach dem Booten unsere Software zu starten. Auf einer Desktop Environment wie Gnome oder KDE können wir komplett verzichten. Lediglich Wayland läuft.
In einem Unterverzeichnis laden wir das boot2qt-manifest für Qt v5.15.1 herunter und initialisieren die Yocto Environment mit dem Google Repo Tool.
~$ mkdir ~/yocto
~$ cd ~/yocto
~/yocto$ wget https://code.qt.io/cgit/yocto/boot2qt-manifest.git/tree/v5.15.1.xml
~/yocto$ repo init -u git://code.qt.io/yocto/boot2qt-manifest -m v5.15.1.xml
~/yocto$ repo sync
Das Image erstellen
Nun müssen wir Yocto mitteilen für welches Gerät wir das Linux Image erstellen wollen. Es wird zum derzeitigen Zeitpunkt Raspberry Pi / 2 / 3 / 4 und Zero unterstützt. Die Variable MACHINE
wird dafür je nach dem auf raspberrypi
, raspberrypi2
, raspberrypi3
, raspberrypi4
oder raspberrypi0
gesetzt.
~/yocto$ export MACHINE=raspberrypi2
~/yocto$ source ./setup-environment.sh
Dann kann das Linux Image erstellt werden. Das wird beim ersten Build einige Stunden dauern können und benötigt 50 GB an freier Festplattenkapazität.
Das Image ist dann im Ordner ~/yocto/build-raspberrypi<$>/tmp/deploy/images/raspberrypi<&>
mit dem Dateinamen b2qt-embedded-qt5-image-raspberrypi<$>.img
zu finden.
Das Image auf die SD Card kopieren
Dann bleibt nur noch das Image zu kopieren. Mit sudo df
ermitteln wir welches Device der SD Card zugewiesen wurde unmounten, wenn nötig und kopieren die Daten mit Disk Dump.
Nun könne wir die SD Card in den Raspberry Pi stecken und von ihr booten.
Die Entwicklerumgebung
Nach dem das Image erstellt ist und der Raspberry Pi läuft soll Qt Creator zum cross compilen für die ARM Architektur eingerichtet werden.
Das zweite Target erstellt die externe Toolchain mit der man dann Qt Anwendungen auf dem Host PC für das Zielsystem erstellen kann.
Nach dem Build Prozess kann man mit einem Shell Script die Toolchain installieren.
~/yocto$ cd build-raspberrypi<&>/tmp/deploy/sdk/
~.../sdk$ sudo ./b2qt-x86_64-meta-toolchain-b2qt-embedded-qt5-sdk-raspberrypi2.sh
Im Installationsverzeichnis befindet sich das Script configure-qtcreator.sh
. Es setzt Umgebungsvariablen für die laufende Terminal Shell Instanz und konfiguriert Qt Creator. Danach kann er aus der laufenden Instanz mit dem Befehl qtcreator &
gestartet werden.
Jedes mal wenn man für den Raspberry Pi kompelieren möchte muss Qt Creator auf diese Art gestartet werden.
Das Deployment der Anwendung
Um später die kompelierte Software auch testen zu können müssen wir den Raspberry Pi in den Einstellungen von Qt als Gerät hinzufügen. Die Einstellungen findet man unter "Extras"⟶"Einstellungen"
Im Einstellungsdialog dann folgende Schritte ausführen:
- auf "Geräte" klicken
- auf "Hinzufügen" klicken
- "Generisches Linux Gerät" wählen
- IP und Benutzer angeben
- einen Schlüssel erstellen
- Danach sollte die Verbindung stehen.
Mit SSH zum Raspberry Pi verbinden
Damit man nun das Programm auch wirklich deployen kann braucht man erst einmal Zugriff auf eine Shell um das laufende Beispiel Programm zu beenden.
Man kann sich als root ohne Passwort über einen SSH Server einloggen. Bei Bedarf kann ein Passwort direkt mit passwd
gesetzt werden.
Mit appcontroller --stop
beendet man das laufende Programm und appcontroller --make-default
lässt beim Systemstart ein anderes Programm automatisch starten.
Geplante Qt Anwendung / App
Einige Einstellungen sollen mittels Touch Display zugägnlich sein. Vor allem um das WLAN konfigurieren zu können. Das verwalten der Bilder und das Konfigurieren werden dann mittels App realisiert.
Zu diesem Thema werden in unregelmäßigen Abständen weitere Posts folgen. Die Anwendung, die App, sowie der komplette Source Code können dann selbstverständlich auch hier und auf Github runtergeladen werden.
Weitere Blog Posts aus dieser Serie
- Embedded Linux Image mittels Yocto erstellen
- Das Bilderrahmen Programm (1)
- Das Bilderrahmen Programm (2)