|
I-RT WS05
|
In den vorausgehenden Vorlesungen wurden vorwiegend Grundbegriffe von Realzeitsystemen vermittelt sowie einige abstrakte Modelle zur Beschreibung solcher Systeme; ein Schwerpunkt lag auch auf der Planung von Taskmengen unter Berücksichtigung der Resourcen und der Deadlines.
In den verbleibenden Vorlesungen soll nun der Versuch unternommen werden, zu zeigen, wie man von solchen abstrakten Modellen von Realzeitsystemen zu konkreten Systemen kommt. Dabei wird zusätzlich thematisiert werden, dass es sich nicht nur um Realzeitsysteme handelt, sondern um eingebettete Realzeitsysteme ('embedded realtime systems').
Die typische Entwicklungssituation wird durch folgendes Schaubild gekennzeichnet:
Im Bereich des Bootens unterscheidet man unterschiedliche Bootstrategien, z.B.:
Von Diskette
Aus einem (Flash-)ROM
Von CD-ROM/DVD
Von Platte
Aus dem Netz (Ethernet...)
Für die Qualität und Zuverlässigkeit eines Zielsystems spielen folgende Aspekte eine Rolle:
Einfache Fehlerbehebung: für alle, die das System verstehen, sollte es einfach sein, Fehler imKode zu beheben.
Erweiterbarkeit: es sollte gut möglich sein, neue Eigenschaften hinzuzufügen.
Konfigurierbarkeit: es muss leicht möglich sein, die notwendigen Programmteile aus den verfügbaren Quellen für bestimmte 'Anwendungen' zusammenstellen zu können.
Voraussagbarkeit: das gestartete Programm sollte sich ensprechend den Vorgaben verhalten.
Fehlerbehebung: im Falle von Fehlern sollten rechtzeitig aussagekräftige Fehlermeldungen generiert werden.
Langlebigkeit: das Programm soll 'möglichst lange' ohne Fehler laufen, auch unter 'schwierigen' Umgebungsbedingngen.
Eine sehr schöne Einführung in die Entwicklung von eingebetteten Systemen am Beispiel des Ziel-Betriebssystem Symbian auf der Hardware von bestimmten Handy-Modellen ist das Buch von Gehrlicher und Rupp [GERLICHER/RUPP 2004]. In diesem Buch wird gezeigt wie man unter Windows (alternativ soll auch Linux möglich sein) eingebettete Anwendungen für das Betriebssystem Symbian (Series 60 Vers.6.1 sowie UIQ Vers.7.0) entwickeln kann, so dass die Funktionalität von Smartphones entsteht. Die dazu notwendige SDKs ('Software Development Kits') kann man kostenfrei direkt von Symbian beziehen (siehe: Symbian OS software development kits. Während Symbian mittlerweile Versionen für C++ und Java anbietet, konzentriert sich das Buch von GERLICHER und RUPP an C++, da damit die besonderen Eigenschaften der Hardware --nach den Autoren-- besser ausgenutzt werden können als unter Verwendung der JVM ('Java Virtual Machine').
In dieser Vorlesung werden wir auf Symbian und dessen Programmierung nicht weiter eingehen, da Symbian kein vollständiges Realzeitbetriebssystem ist und ausserdem der Quellkode nicht offen liegt; damit ist Symbian nur als 'black box' nutzbar.
![]() |
Bild:
Linux-Kernel Übersicht |
Da die RTAI-Funktionalitäten als Module nachgeladen werden, soll
hier Linux soweit erklärt werden, wie es zum Verständnis dieses
Zusammenhanges notwendig ist.Fuer weitere Informationen sei verwiesen
auf die Webseite des
hervorragenden Buches von Alessandro RUBINI/Jonathan
CORBET [2nd Edition June 2001], hier besonders Kap.2 (dieses Buch
ist komplett online verfügbar, dazu die Beispiele im
Quellkode!)(Interessant erscheint auch das Buch von (Abott, 2004), das
mit Software auf CD kommt; allerdings konnte ich noch nicht alle
Details
testen).
Module sind Teile des Betriebsystems, die sich im laufenden Betrieb einfügen und entfernen lassen.
Es sind Programme, die im Kern laufen. Linuxmodule werden mit der Programmiersprache C entwickelt und sind im einfachsten Fall folgendermaßen aufgebaut (Beispiel von der Webseite zu Rubini):
/*
* $Id: hello.c,v 1.7 2000/08/17 11:11:48 rubini Exp $
*/
#define MODULE
#include <linux/module.h>
int init_module(void) { printk("<1>Hello, world\n"); return 0; }
void cleanup_module(void) { printk("<1>Goodbye cruel world\n"); }
Ein Linux bzw. RTAI-Linux Modul hat im Gegensatz zu einem herkömmlichen C-Programm keine main()-Funktion. Es bestehet aus mindestens diesen zwei Funktionen: int init_module(void) und void cleanup_module(void).
Für die Ausgabe kann die bekannte C-Funktion printf von einem Modul nicht benutzt werde, dafür bietet der Kern die Funktion printk (RTAI: rt_printk).
Die Präprozessoranweisung #define MODULE sorgt dafür, dass der für die Modul- und Kernelprogrammierung notwendige Anteil in den Headerdateien Verwendung findet.
Besteht das Programm(Modul) aus mehreren Dateien, wird zunächst jede Datei für sich kompiliert (Option ld -r) und es wird eine einzige Objektdatei Moduol.o erzeugt. Dann werden alle Module miteinander verbunden. Damit entsteht eine einzige ausführbare Datei.
Dies sei hier an einem Beispiel mit einem Kernel der Version 2.4.xx durchgespielt (mit Version 2.6.xx funktioniert es nicht, da das Modulformat anders ist!).
Will man das Modul kompilieren, ohne den Kernel konfiguriert zu haben, ergibt sich folgende Fehler-Meldung:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # gcc -I /usr/src/linux -I/usr/src/linux/include -O2 -Wall -D__KERNEL__ -DCONFIG_M386 -c hello.c
In file included from /usr/src/linux/include/linux/module.h:10,
from hello.c:5:
/usr/src/linux/include/linux/config.h:4:28: linux/autoconf.h: Datei oder Verzeichnis nicht gefunden
In file included from /usr/src/linux/include/linux/list.h:241,
from /usr/src/linux/include/linux/module.h:12,
from hello.c:5:
/usr/src/linux/include/linux/prefetch.h:13:26: asm/prefetch.h: Datei oder Verzeichnis nicht gefunden
In file included from /usr/src/linux/include/linux/module.h:299,
from hello.c:5:
/usr/src/linux/include/linux/version.h:6:2: #error "The kernel sources in /usr/src/linux are not yet configured."
/usr/src/linux/include/linux/version.h:7:2: #error "Please run 'make cloneconfig && make dep' in /usr/src/linux/"
/usr/src/linux/include/linux/version.h:8:2: #error "to get a kernel that is configured like the running kernel."
/usr/src/linux/include/linux/version.h:9:2: #error "Alternatively, you can copy one of the config files"
/usr/src/linux/include/linux/version.h:10:2: #error "arch/$ARCH/defconfig.* to .config, and run"
/usr/src/linux/include/linux/version.h:11:2: #error "'make oldconfig && make dep' to configure the kernel"
/usr/src/linux/include/linux/version.h:12:2: #error "for that configuration."
In file included from hello.c:5:
/usr/src/linux/include/linux/module.h:301: error: parse error before "UTS_RELEASE"
Nach Bereitstellung der Sourcen und Ausführung des folgenden Befehls:
make cloneconfig && make dep
ist der Kernel konfiguriert und in der Datei /usr/src/linux/include/linux/version.h finden sich dann folgende Daten:
#define UTS_RELEASE "2.4.21-99-default"
#define LINUX_VERSION_CODE 132117
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
Wiederholt man jetzt den Befehl zum Kompilieren gibt es keine Fehlermeldung mehr:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # gcc -I /usr/src/linux -I/usr/src/linux/include -O2 -Wall -D__KERNEL__ -DCONFIG_M386 -c hello.c
Der folgende Aufruf des Moduls produziert zwar Warnungen, aber das Modul wird geladen und ausgeführt:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # insmod ./hello.o
Warning: loading ./hello.o will taint the kernel: no license
See http://www.tux.org/lkml/#export-tainted for information about tainted modules
Module hello loaded, with warnings
Da das Modul von einem xterm-Fenster aufgerufen wird, erscheint die Ausgabe nicht direkt auf dem Bildschirm, sondern wird der Datei /usr/var/messages angefügt:
Dec 4 19:16:01 turing kernel: Hello, world
Wird das Modul wieder entfernt:
turing:/home/gerd/public_html/fh/I-RT04/VL/VL9 # rmmod hello
Dann erscheint die Meldung bei der Entfernung des Moduls wieder in /usr/var/messages:
Dec 4 19:41:20 turing kernel: Goodbye cruel world
Für weitere Details siehe das Kapitel 2 (Webversion) (Kapitel 2 (lokale Version) des hervorragenden Buches von Alessandro RUBINI/Jonathan CORBET [2nd Edition June 2001]
Diese Vorlesungen leiten über von den abstrakten Modellen von Realzeitsystemen zu mindestens einem konkreten Realzeit-System. Die wichtigsten 'Elemente eines abstrakten Realzeitsystems sind im nachfolgenden Schaubild nochmals festgehalten. Es sind die Ereignisse, die Tasks, die verfügbare Resourcen sowie ein Schedulingmechanismus.
Realzeitsysteme
Als Beispiel für ein konkretes Realzeitsystem hatten wir uns für RTAI entschieden, das im Verbund mit Linux ein für viele kleinere Anwendungen günstige Lösung darstellt. In den letzten beiden Vorlesungen hatten wir kurz die Grundstruktur Linux untersucht und uns damit bekannt gemacht, welche Rolle Module unter Linux spielen. Die Motivation dafür ergab sich daraus, dass RTAI unter Linux durch Aufrufen von Modulen installiert wird (siehe nächstes Schaubild).
Realzeitsysteme mit Linux und RTAI
In dr heutigen Vorlesung werden wir uns mit ersten Eigenschaften von RTAI selbst vertraut machen sowie anhand eines einfachen Beispiels betrachten, wie wir eine erste kleine Anwendung unter RTAI realisieren können.
Als Quelle für die folgende Darstellung von RTAI siehe einmal das Usermanual der Sysgo AG zu ELinOS v2.2 sowie die Beiträge des Entwicklerteams von RTAI ( siehe [DIAPM-RTAI [2000]: DIAPM RTAI - Beginner's Guide (Weblocation), (Lokal), Realtime Application Interface for Linux (Erklärung der Systemaufrufe) + Programming Guide).
In einer Kurzbeschreibung kann man sagen, dass es sich bei RTAI um einen kleinen Echtzeitkern handelt, der Linux in einer eigenen Task ablaufen läßt. Linux ist dabei die Idletask, die nur dann aufgerufen wird, wenn keine andere Echtzeittask lauffähig ist. Linux-Interrupts werden vom RTAI abgefangen und in eine Warteschlange gelenkt. Existiert keine Realtime-Routine, so wird das Interrupt an den Standard-Linuxkernel weitergereicht. Die entsprechende Routine wird dann ausgeführt um den Interrupt zu behandeln. Unter RTAI werden Realtime-Programme als Module implementiert, was ihre Funktionalität beschränkt, weswegen werden mit RTAI nur die zeitkretischen Teile des Programms implementiert, alles andere wird von Linux durchgeführt. Dies ist möglich, da RTAI dem Linuxkernel erlaubt, alle seine Funktionen und Dienste beizubehalten.
Ereignisse unter RTAI
Beim Eintreten bestimmter Ereignisse startet RTAI benutzerdefinierte Programmteile. Es gibt zwei Arten von Ereignissen (Interrupts):
Intern: Zeitgesteuerte Interrupts (Timer Interrupts)
Extern: externe Interrupts
RTAI Scheduler
Da Linux ein Multitaskingsystem ist dh. mehrere Programme können gleichzeitig ausgeführt werden müssen zur Laufzeit ständig Entscheidungen über die Zuteilung des Prozessors zu den einzelnen Programmen erfolgen. Diese Entscheidungen, die in Abhängigkeit von dem gewünschten Systemverhalten, der eingestellten Prozesszuteilungsstrategie und der dem Betriebssystem bekannten Prozessparameter gefällt werden, übernimmt der Scheduler. Der Scheduler eines Betriebssystems kann abhängig von der Implementierung bei folgenden Aktivitäten aufgerufen werden:
RTAI stellt drei verschiedene Scheduler-Varianten zur Verfügung. Diese unterscheiden sich dadurch, dass sie zum einen für den Einsatz auf Ein-Prozessor-Maschinen und zum anderen für den Einsatz auf Multi-Prozessor-Maschinen spezialisiert sind. In der Kategorie der Multi-Prozessor-Scheduler gibt es weiterhin zwei Varianten, eine in der die Mehr-Prozessor-Maschine als SMP-(Symmetric Multi-Processor) System und eine in der sie als mehrere Einzel-Prozessoren gesehen wird. Benannt sind diese Varianten nach dieser Eigenschaft ( UNI-Prozessor- , SMP- und Multi-Uni-Prozessor-Scheduler). Alle diese Varianten können sowohl im so genannten Oneshot-Timer-Mode (also der Timer läuft einmal ab und unterbricht dann einmal) oder im Periodic-Timer-Mode betrieben werden (in dem der Timer das System periodisch unterbricht).
Uni-Prozessor-Scheduler: Dieser Scheduler ist recht simpel. Er besteht aus mehreren Listen mit verschiedenen Prioritäten, welche er linear durchläuft und zur Vermeidung von Prioritätenumkehr das Priority-Inhartitance-Protocol nutzt. In dieser Konfiguration ist Linux ein Echtzeit-Prozess wie jeder andere, allerdings mit geringster Priorität.
SMP-Scheduler: Der SMP-Scheduler unterscheidet sich vom Uni-Prozessor-Scheduler dadurch, dass er die Prozesse auf die zur Verfügung stehenden Prozessoren verteilen kann. Das ermöglicht ein paar zusätzliche Dienste, so können zum Beispiel die Paare CPU,Prozess) und (CPU,IRQ) konkret zugeordnet werden. Außerdem können die Timer des APIC (Advanced Programmable Interrupt Controller) der SMP-Architektur genutzt werden.
Multi-Uni-Prozessor Scheduler: Wie der Name schon sagt, sieht dieser Scheduler die SMP-Maschine als eine Ansammlung von Einzel-Prozessor-Maschinen, was bedeutet, dass jeder Prozessor seine Timer unabhängig von den anderen programmieren kann. Also können die Timer-Modi periodic und oneshot abhängig von der CPU verschieden sein.
Was unterscheidet ein eingebettetes System von einem normalen System?
Welche Bedeutung haben die Begriffe 'target system' und 'host system' im Kontext der Entwicklung von eingebetteten Systemen?
Warum ist der Bootvorgang bei eingebetteten Systemen so wichtig?
Welche Arten von Bootmedien kennen Sie?
Welche Rolle spielt der Bootmanager beim Booten?
Welche Bootmanager kennen sie?
Was ist mit folgenden Eigenschaften im Kontext von eingebetteten Systemen gemeint: Modularität, Einfache Fehlerbehebung, Konfigurierbarkeit, Voraussagbarkeit, Langlebigkeit
Welche Eigenschaften zeichnen das Betriebssystem Symbian aus?
Was spricht gegen den einsatz von Linux als eingebettetem System, was dafür?
Welches sind die wichtigsten Komponenten eines Linux-Prozesses?
Mit welchen Methoden können Linux-Prozesse untereinander kommunizieren?
Was unterscheidet den Kernel-Mode vom User-Mode?
Auf welche Weise kann die Aussenwelt mit dem Linux-Kernel kommunizieren?
Was verstehen Sie darunter, dass Linux in Modulen
organisiert
ist?
Wie ist ein Modul aufgebaut?
Wie wird ein Modul aktiviert?
Wie können Module untereinander kommunizieren?
Wozu benötigt man ein init_module und ein cleanup_module?
Was ist RTAI?
Wie ist RTAI relativ zum Linuxkernel zu sehen?
Was macht der RTAI-Scheduler?
Welche Typen von RTAI-Schedulern kennen Sie?