Einführung
In diesem Blog-Beitrag stellen wir die Verwendung von Docker-Containern als Entwicklungsumgebung für ein Embedded Linux BSP-Entwicklungsprojekt auf Basis von Yocto und OpenEmbedded vor.
Heutzutage sind Docker und Container im Allgemeinen aufgrund ihrer Vielseitigkeit bei der Lösung von Anwendungsabhängigkeiten und Paketierungsproblemen praktisch überall zu finden. Bei DigitalGate nutzen wir Docker für viele Aufgaben, von CI-Pipelines bis hin zu skalierbaren IoT-Geräten, die über eine generische Schnittstelle für die Integration von Drittanbieteranwendungen verfügen müssen. Als IDE werden wir Visual Studio Code verwenden, da es über hervorragende Remote-Entwicklungsfunktionen verfügt. Visual Studio Code ist eine hervorragende IDE, wenn es um die Entwicklung innerhalb von Docker-Containern geht.
Ein Vorteil der Entwicklung von Embedded Linux in Docker-Containern ist die Plattformunabhängigkeit der Entwicklungsumgebung. Alle Abhängigkeiten des Build-Systems sind in den Docker-Containern verpackt. Entwickler müssen nur Docker installiert haben. Solche Setups sind ideal für Unternehmensumgebungen, in denen z. B. Windows tatsächlich die Plattform für Entwicklungsmaschinen ist.
Einrichtung der Host-Umgebung
Als ersten Schritt beim Einrichten unserer Entwicklungsumgebung müssen wir Docker auf unserem Rechner installieren. In diesem Artikel verwenden wir einen Windows 10-Rechner mit installierter Docker-Version 19.03.13. Die Schritte zur Installation von Docker finden Sie unter folgendem Link: https://docs.docker.com/desktop/windows/install/. Sobald Docker installiert ist, werden wir mit der Implementierung unserer Docker-Compose-Dateien fortfahren. Die Dateien beschreiben unsere Entwicklungsumgebung und die Werkzeuge, die wir auf ihr installieren müssen. Die zu installierenden Pakete sind in der Yocto-Benutzeranleitung angegeben https://www.yoctoproject.org/docs/1.8/yocto-project-qs/yocto-project-qs.html
Die Schritte zum Einrichten der Umgebung und zur Installation der erforderlichen Abhängigkeiten für Yocto werden in unserer Dockerdatei durchgeführt, das das Basis-Image definiert, das wir verwenden werden.
Docker-Compose-Skript
Die folgende Docker-Compose-Datei implementiert unsere Entwicklungsplattform und beschreibt die folgenden Punkte:
- Betriebssystem, das wir innerhalb des Docker-Containers emulieren werden, in diesem Fall Ubuntu 18.04;
- die verschiedenen Volumes, die wir verwenden werden, um die Projektdateien vom Host-PC im Docker-Container abzubilden;
- Netzwerkschnittstellen, die wir mit dem Host teilen werden. In diesem speziellen Fall werden wir im Bridged-Modus arbeiten, damit der Container direkten Zugriff auf die Netzwerkschnittstellen des Host-Rechners hat.
version: "2"
services:
yocoto-dev-enviroment:
build: .
networ_mode: bridge
volumes:
- ../:/yocoto-dev-enviroment/
working_dir: /yocoto-dev-enviroment
command: sleep infinity
environment:
- DEBIAN_FRONTEND=noninteractive
Bild der Entwicklungsumgebung
Das Docker-Image, das wir für den Entwicklungs-Docker-Container verwenden werden, basiert auf Ubuntu 18.04. In der Docker-Datei können wir alle Pakete angeben, die wir installieren müssen. Auf diese Weise werden alle von Yocto benötigten Pakete installiert, während der Container gebaut wird.
RUN apt-get install -y \
bc \
build-essential \
chrpath \
cpio \
debianutils \
diffstat \
dos2unix \
fop \
g++-multilib \
gawk \
gcc-multilib \
git-core \
git-lfs \
iputils-ping \
libegl1-mesa \
libncurses5-dev \
libsdl1.2-dev \
pylint3 \
python3 \
python3-dev \
python3-git \
python3-jinja2 \
python3-pexpect \
python3-pip \
socat \
texinfo \
tmux \
unzip \
vim \
wget \
xsltproc \
xterm \
openssl \
tree \
xz-utils
Sobald alle erforderlichen Pakete installiert sind, können wir die Locales und Berechtigungen für die verschiedenen Verzeichnisse auf dem Container-Dateisystem so konfigurieren, dass die Build-Verzeichnisse und Artefakte mit dem Host-PC und dem Board-Bootloader, der das Linux-Image über Ethernet bootet, gemeinsam genutzt werden können.
RUN apt-get update && apt-get install -y \
apt-utils locales sudo && \
dpkg-reconfigure locales && \
locale-gen en_US.UTF-8 && \
update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
ENV LANG en_US.utf8
Ein zusätzlicher Schritt ist die Konfiguration eines Nicht-Root-Benutzers. Standardmäßig hat der Container nur den Root-Benutzer, aber Bitbake kann nicht unter dem Root-Benutzer laufen. Wir müssen einen Benutzer erstellen und ihn der Sudoers-Gruppe hinzufügen, damit er Befehle als root ausführen kann.
ARG host_uid=1001
ARG host_gid=1001
RUN groupadd -g $host_gid $USER_NAME && \
useradd -g $host_gid -m -s /bin/bash -p $(openssl passwd -crypt $PASS) -u $host_uid $USER_NAME && \
echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
Eine praktische Konfiguration ist der Wechsel zum Nicht-Root-Benutzer am Ende der Dockerdatei, da alle Befehle, die wir innerhalb des Docker-Containers ausführen, unter einem Nicht-Root-Benutzer laufen müssen.
USER $USER_NAME
Wenn das Skript fertig ist, können wir es mit der Visual Studio-Erweiterung für Remote-Container ausführen. Dies wird den Docker-Daemon veranlassen, unser Image zu erstellen und den Yocto-Arbeitsbereich innerhalb des neu erstellten Containers zu öffnen.
Von nun an können wir mit der Einrichtung der Bitbake-Umgebung für die Erstellung unserer Images fortfahren. In diesem speziellen Beispiel werden wir ein benutzerdefiniertes Image für das sama5d2 xplained Board erstellen.
Um die Initialisierung der Build-Umgebung für bitbake zu automatisieren, werden wir ein kleines Shell-Skript verwenden. Es führt folgende Aktionen durch.
Es klont alle für den Build erforderlichen Ebenen:
- Poky;
- Openembedded;
- meta-atmel;
- meta-aws;
- meta-qt.
Quelltext des Bitbake-Init-Skripts, das unsere Build-Umgebung einrichtet. Darin können wir verschiedene Bitbake-Befehle für Layer, Rezepterstellung, Maschinenkonfiguration usw. ausführen.
Fügt der Build-Konfiguration mit dem Befehl bitbake-layers add-layer die erforderlichen Schichten hinzu.
#!/bin/bash -xe
#layers on which our image depends
POKY_REPO=git://git.yoctoproject.org/poky.git
OPENEMBEDDED_REPO=git://git.openembedded.org/meta-openembedded.git
# Setup all source directories
if [ ! -d /opt/build ] ; then
git clone "$POKY_REPO" -b dunfell /opt/build/poky
git clone "$OPENEMBEDDED_REPO" -b dunfell /opt/build/meta-openembedded
fi
# initialize build directory
source /opt/build/poky/oe-init-build-env /opt/build
# add all required layers to the build
bitbake-layers add-layer meta-openembedded/meta*/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-atmel/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-aws/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-custom-app/
Sobald dies geschehen ist, wird das Verzeichnis in das bitbake-Verzeichnis geändert. Hier können wir mit der Erstellung eines Image beginnen. Zum Beispiel ein Micro-Chip-Graphics-Image, das Unterstützung für die Grafikschnittstellen auf der Karte bietet.
Schlussfolgerung
Zusammenfassend lässt sich sagen, dass die Verwendung einer vollständigen Docker-Entwicklungsumgebung für die Entwicklung von Embedded Linux ein effizienter Weg ist, um reproduzierbare Builds und Setups für ein ganzes Team zu gewährleisten. Gleichzeitig ermöglicht es uns, parallel an mehreren Projekten mit unterschiedlichen Anforderungen an die Einrichtung auf derselben Maschine zu arbeiten. Eine Docker-Entwicklungsumgebung ermöglicht es uns auch, eine saubere Entwicklungsmaschine zu behalten, die nicht mit projektspezifischen Paketen verunreinigt ist.
Weitere Artikel anschauen:
Important New C++ Features
C++ 20 and 23 have a lot of new features which can reduce boilerplate code, increase efficiency and make the code drastically more readable.
Embedded World 2023
DigitalGate freut sich, seine Teilnahme an der Embedded World 2023 anzukündigen, die vom 14.03. bis 16.03. in Nürnberg stattfindet. Kommen Sie und treffen Sie uns an unserem
Type erasure in C++
What is it? Type erasure is the technique used to hide the type meta-data of some data. When we store and manage data in
QEMU-Entwicklung
In Anbetracht der aktuellen Entwicklungen auf dem Weltmarkt, insbesondere der weltweiten Chip-Knappheit, gibt es einige Probleme, die bei
Yocto DevTool
Ein Kommandozeilenprogramm namens DevTool dient als Grundlage für das erweiterbare SDK. Mithilfe dieses Tools können Sie Software mit dem erweiterbaren SDK erstellen,
Vorteile des Outsourcings
Nowadays, most embedded systems have functionalities implemented in software.The usage of embedded software by electronics manufacturers for expanded functionality, improved quality, and reusability is