- Posts: 11
- Thank you received: 8
Echtzeitfähige Linux-Systeme: Eine Beispielumsetzung anhand des Raspberry Pi's
- Rainer Poisel
- Offline
- New Member
Less
More
10 years 3 months ago - 10 years 2 weeks ago #31
by Rainer Poisel
Echtzeitfähige Linux-Systeme: Eine Beispielumsetzung anhand des Raspberry Pi's was created 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.
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:
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:
Anschließend können die restlichen erforderlichen Einstellungen mit folgendem Kommando gemacht werden:
Hier eine Zusammenfassung:
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:
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!):
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:
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:
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:
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:
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.
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:
- github.com/rpoisel/cycle-time-test
- rt.wiki.kernel.org/index.php/Cyclictest
- rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO
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
9 years 10 months ago - 9 years 10 months ago #65
by Karsten Hoffmann
Replied by Karsten Hoffmann on topic Echtzeitfähige Linux-Systeme: Eine Beispielumsetzung anhand des Raspberry Pi's
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.