Skip to main content

Echtzeitfähige Linux-Systeme: Eine Beispielumsetzung anhand des Raspberry Pi's

More
10 years 3 months ago - 10 years 2 weeks ago #31 by Rainer Poisel
Kurzfassung

Dieser Artikel beschreibt die erforderlichen Schritte, um ein Linux-System echtzeitfähig zu machen. Neben einer allgemeinen Einführung in das Thema wird eine beispielhafte Umsetzung anhand des Raspberry Pi's erläutert.

Einführung

Durch die Medien wurde in der Vergangenheit oftmals ein falsches Bild vom Thema "Echtzeitsysteme" vermittelt. So geht es etwa nicht darum allgemeine Leistungsfähigkeit von Computersystemen zu steigern oder gar die Antwortzeit auf Null zu reduzieren. Vielmehr will erreicht werden, dass das Antwortzeitverhalten von Computersystemen vorhersehbar wird und dieses sich, um es in anderen Worten auszudrücken, innerhalb festgelegter Grenzen bewegt.

Steven Rostedt erklärt die Zusammenhänge in einem Interview ausführlicher. Resümierend lässt sich festhalten, dass man sich als Entwickler darüber im Klaren sein sollte, ob tatsächlich Echtzeitverhalten für das aktuelle Szenario notwendig ist. Das Antwortzeitverhalten von echtzeitfähigen Linuxsystemen lässt sich momentan nicht mathematisch beweisen. Weiters erläutert Rostedt, dass der beste Einstieg in die Materie das Anwenden des PREEMPT_RT-Patches ist. Diesem Ratschlag werden wir in den folgenden Kapiteln folge leisten.

Mit vorhersehbarer Verzögerung: Echtzeit im Linux-Kernel

Der Vorteil des PREEMPT_RT-Patches gegenüber den anderen Echtzeitimplementierungen, wie z. B. Xenomai oder RTAI bzw. RTLinux, liegt in der Weiterverwendbarkeit bereits vorhandener, bekannter Betriebssystemmechanismen. Voraussetzung für ein echtzeitfähiges System ist also ein entsprechender Kernel. Ein für den Raspberry Pi angepasstes Quellenverzeichnis kann von der Github-Projektseite bezogen werden. Achten Sie darauf, dass genuegend Speicherplatz für das Kompilieren des Kernels (ca. 1.5 - 2 GB) vorhanden ist.
Code:
git clone --depth=1 https://github.com/raspberrypi/linux.git

Grundlegende Anleitungen zur (Cross-)Kompilierung von Raspberry Pi Linux-Kerneln bieten Building and Deploying Raspberry PI Kernel und Kernel buildling . Diesen Anleitungen kann auch entnommen werden, wie man zu einer funktionierenden Toolchain kommt. Diese befindet sich am System des Authors im Verzeichnis /usr/local/toolchains/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin.

Nach einem Wechsel in das linux-Verzeichnis kann der PREEMPT_RT-Patch angewandt werden. Wichtig ist in diesem Zusammenhang den zum Kernel passenden Patch zu verwenden. Den aktuell passenden bezieht man von der Homepage des Linux-Kernels .

Vor dem eigentlichen Anwenden empfiehlt es sich die Anwendbarkeit zu überprüfen. Dies gelingt mit der "--dry-run"-Option:
Code:
xcat patch-3.12.19-rt30.patch.xz | patch -p 1 --dry-run

Im günstigsten Fall wird das Kommando ohne Fehlermeldungen ausgeführt. Im oben angeführten Beispiel konnte ein Makefile nicht erfolgreich gepatcht werden, was jedoch durch Handarbeit mit einem Texteditor einfach zu korrigieren war. Der tatsächliche Patch-Vorgang wird durch das Weglassen der Option "--dry-run" erzielt.

Eine funktionierende Standard-Konfiguration wird mit folgendem Kommando erstellt:
Code:
ARCH=arm CROSS_COMPILE=/usr/local/toolchains/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- make bcmrpi_defconfig

Anschließend können die restlichen erforderlichen Einstellungen mit folgendem Kommando gemacht werden:
Code:
ARCH=arm CROSS_COMPILE=/usr/local/toolchains/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- make xconfig

Hier eine Zusammenfassung:
Code:
CONFIG_PREEMPT_RT_FULL=y CONFIG_HIGH_RES_TIMERS=y

Weiters ist es wichtig alle Energiespeicheroptionen zu deaktivieren. Typische Schlüsselwörter sind in diesem zusammenhang "APM" (Advanced Power Management) und "ACPI" (Advanced Configuration and Power Interface).

Der eigentliche Übersetzungsvorgang wird anschließend mit folgender Befehlszeile in Gang gesetzt:
Code:
ARCH=arm CROSS_COMPILE=/usr/local/toolchains/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- make -j <Anzahl-CPU-Kerne + 1>

Das Übersetzen nimmt einige Zeit in Anspruch. In der Zwischenzeit kann ein abgespecktes System von linuxsystems.it bezogen werden. Dieses dient als Ausgangsimage und wird im Folgenden an den Einsatz als Echtzeitsystem angepasst. Nach dem Entzippen kann das Image per "dd" auf eine SD-Karte passender Grüße übertragen werden (bitte darauf acnten, die richtige Gerätedatei, hier /dev/sdb, zu verwenden!):
Code:
dd if=raspbian_wheezy_20130923.img of=/dev/sdb

Nach Beendigung des Kernel-Übersetzungsvorganges befindet sich das für den Echtzeiteinsatz benötigte Resultat im Kernel-Quellverzeichnis unter arch/arm/boot/zImage und kann nach dem Mount-Vorgang auf die erste Partition auf der SD-Karte mittels "cp"-Kommando übertragen werden:
Code:
mount /dev/sdb1 /mnt/temp cp arch/arm/boot/zImage /mnt/temp/kernel-rt.img

Bei der Gelegenheit kann gleich der Bootloader angepasst werden, sodass dieser beim nächsten Neustart des Raspberry Pi's bereits mit dem Realtime-Kernel startet. Dazu muss in der "config.txt"-Datei die "kernel="-Zeile angepasst werden, sodass auf das neue Image verwiesen wird: "kernel=kernel-rt.img". Sollte die Zeile fehlen, dann muss diese am besten gleich am Beginn der Datei eingefügt werden. Weitere mögliche Optionen des Bootloaders sind im eLinux-Wiki dokumentiert. Weiters sollten dem Linux-Kernel laut RT_PREEMPT-HowTo die Option "lapic" und laut Raspberry Pi Forum die Option "sdhci_bcm2708.enable_llm=0" hinzugefügt werden. Dies kann in der Datei "cmdline.txt" in der ersten Partition auf der SD-Karte eingestellt werden.

Zum Abschluss werden noch Kernel-Module übersetzt bzw. zusammengestellt und auf die SD-Karte übertragen (vorher die erste Partition unmounten!). Mit Hilfe der folgenen Kommandos wird dies bewerkstelligt:
Code:
mount /dev/sdb2 /mnt/temp ARCH=arm CROSS_COMPILE=/usr/local/toolchains/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=/tmp/modules.rt make modules_install cp -rp /tmp/modules.rt/lib/* /mnt/temp/lib

Nach dem Vornehmen der anderen gewünschten Optionen (z. B. IP-Adresse, Benutzeroptionen wie Passwörter, usw.) direkt auf der SD-Karte stehen nach einem Start des Raspberry's mit unserem prepariertem Image den ersten Gehversuchen mit unserem Echtzeitsystem nicht's mehr im Wege.

Erste echtzeitfähige Gehversuche

Programme, die die Echtzeitfähigkeit des Linux-Kernels demonstrieren gibt es mehrere:

Und ein erster Testlauf zeigt vielversprechende Ergebnisse:

Testlauf ohne Echtzeiterweiterungen:
Code:
root@raspberry-pi:/tmp# ./cyclictest -p95 -n # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.37 0.26 0.14 1/66 2132 T: 0 ( 2123) P:95 I:1000 C: 25495 Min: 15 Act: 40 Avg: 79 Max: 2008 root@raspberry-pi:/tmp# ./cycle-time Count: 13241 Min: 0 Max: 2982 Avg: 77.986632

Sämtliche Zeiten sind in µs (Mikrosekunden) angegeben. Beim cyclictest betrug die schlechteste Antwortzeit 2ms, beim cycle-time Versuch sogar fast 3ms.

Testlauf mit Echtzeiterweiterungen:
Code:
root@raspberry-pi:/tmp# ./cyclictest -n # /dev/cpu_dma_latency set to 0us policy: other/other: loadavg: 0.26 0.14 0.16 1/82 2294 T: 0 ( 2294) P: 0 I:1000 C: 876 Min: 48 Act: 95 Avg: 157 Max: 4291 root@raspberry-pi:/tmp# ./cyclictest -n -p95 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.24 0.14 0.16 1/82 2296 T: 0 ( 2296) P:95 I:1000 C: 1622 Min: 15 Act: 37 Avg: 29 Max: 110 root@raspberry-pi:/tmp# ./cycle-time Count: 10269 Min: 0 Max: -33 Avg: 5.036907 root@raspberry-pi:/tmp# ./cycle-time Count: 15842 Min: 0 Max: 40 Avg: 4.552203 root@raspberry-pi:/tmp# ./cycle-time Count: 23567 Min: 0 Max: -28 Avg: 4.946960

Nach mehreren Testläufen mit den Echtzeiterweiterungen lässt sich festhalten, dass die schlechtesten Antwortzeiten im Bereich um die 100 µs betragen. Wesentlich zum Ergebnis trägt hierbei die Prozess-Priorität bei (siehe Ergebnis 4291 µs). Um so höher deren Wert, umso besser das Antwortzeitverhalten.

Im Rahmen der Testläufe wurde noch nicht untersucht, wie gut sich ein Programm, das mehrere Threads parallel ausführt, im Echtzeiteinsatz verhält. Dies wird Bestandteil der nächsten Teststellungen.
Last edit: 10 years 2 weeks ago by Rainer Poisel. Reason: Some links were broken or expired
The following user(s) said Thank You: Karsten Hoffmann, Goltz

Please Anmelden or Create an account to join the conversation.

  • Karsten Hoffmann
  • Visitor
  • Visitor
9 years 10 months ago - 9 years 10 months ago #65 by Karsten Hoffmann
Please login to view the answers
Last edit: 9 years 10 months ago by Karsten Hoffmann.

Please Anmelden or Create an account to join the conversation.

Powered by Kunena Forum