u
|
I-RT04 REALZEITSYSTEME WS04
|
Die bisherige Vorlesung hat relativ abstrakt Grundbegriffe über Realzeitsysteme vermittelt, Systeme, die sich letztlich auf die Begriffe Ereignisse, Tasks und Resourcen zurückführen lassen. Für eine theoretische Behandlung bildet dies eine unausweichliche Grundlage. Für eine weitere Vertiefung dieser theoretischen Behandlung sei verwiesen auf die Bücher [COTTET et al 2002], [KLEIN et al 1993] und [KOPETZ 2001].
In den folgenden Vorlesungen sollen nun konkrete Systeme betrachtet werden, und zwar speziell das Real Time Application Interface [RTAI] wie es im Kontext des Linux Betriebssystems zum Einsatz kommt.
Momentan sind noch kaum Veröffentlichungen bekannt, in denen die Installation und Nutzung von RTAI auch für Einsteiger beschrieben wird. Herr Houssaini hatte sich vorab zum WS04 die Aufgabe gestellt, einen Einstieg für RTAI mit Linux zu erarbeiten und --wie man sehen kann-- ist dies im ersten Anlauf sehr gut gelungen. Wir werden daher in den nächsten Vorlesungen so weit wie möglich seinen Ausarbeitungen folgen.
Da das RTAI für seinen Betrieb Linux voraussetzt, müssen die Eigenschaften von Linux soweit behandelt werden, dass der Umgang mit RTAI transparent wird. Zum Einstieg betrachten wir dazu eine konkrete Realzeitanwendung, wie Sie Herr Houssaini herausgearbeitet hat.
Auf seiner Webseite entwickelt Herr Houssaini das Beispiel einer Realzeitanwendung, bei der mit Hilfe eines Überwachungsmonitor ein Patient beobachtet wird. Bei Sauerstoffmangel im Körper oder bei Herzrhythmusstörungen wird der Monitor einen Alarm auslösen. Das System dient dazu, den Patienten vor weiteren Schäden zu schützen.
Es muss schnell und sicher mit allen Situationen, in denen sich der Patient befinden kann, interagieren. Die Nutzung des System muss für den Benutzer(in diesem Fall der Arzt, Pfleger...), leicht und verständlich sein. Eine grafische Benutzeroberfläche dürfte dabei eine wichtige Rolle spielen.
Monitor
Überwachung:
Das System misst die Sättigung und den Puls durch eine Pulszählung, wobei die Impulse von einem an dem Patienten angebrachte Sensor stammen.
Überwachung der Herzfrequenz:
Das System soll dem Benutzer (in diesem Fall Arzt, Pfleger, Krankenschwester...) die Herzfrequenz auf dem Anzeigeschirm zur Verfügung stellen. Ein Wertbereich ist vorher einzustellen und ist vom Alter Abhängig (bei kleinen Kindern von 70 bis 120).
Überwachung der Sättigung:
In bestimmten Abständen soll das System die Sättigung (Sauerstoffmenge im Blut) messen (periodische Task) und in % zeigen.
Erreicht dieser Wert eine Grenze, die vorher manuell eingestellt worden ist, wird entweder der Alarm ausgelöst oder dem Patient automatisch Sauerstoff zu Verfügung gestellt. Hilft dies nicht, wird ein Alarm ausgelöst.
Akkuüberwachung :
Die Akkuleistung soll vom System kontrolliert werden, und Alarm auslösen, wenn diese zu niedrig ist. Eine Anzeigemöglichkeit soll vorhanden seien. Steuerung:
Das System soll das Sauerstoffgerät (Ventil) steuern.
Bei nicht manueller Einstellung ist der Sauerstoff zunächst abgestellt. Meldet das System einen Sauerstoffbedarf soll es zuerst Alarm schlagen (Alarmstuffe Orange), und muss gleichzeitig dafür gesorgt werden, dass der Patient mit Sauerstoff versorgt wird. Der Sauerstoff muss mit einem bestimmten Durchfluss fließen, bis die Sättigung im Körper normal wird. Geschieht dies nicht, dann soll die Alarmstufe Rot eingeschaltet werden.
Dazu gehören noch folgende Funktionen:
Ventil aktivieren
Ventil deaktivieren
Durchfluss erhöhen
Durchfluss senken
Stoppen
Beenden
Betätigt der Pfleger Aktivieren und stellt er einen bestimmten Durchfluss ein, so wird das System dies übernehmen und als Default einsetzen.
Anforderungsmodell
In diesem Abschnitt wird die Beziehung Pfleger-System, Patient-System, Sauerstoffgerät-System erläutert.
Das System verfügt über Schnittstellen zum Pfleger, zum Patient und zum Sauerstoffgerät. Diese Elemente und die dazwischen fließenden Signale sind im unteren Diagramm beschrieben
Monitor Anforderungen
Entwicklung und Planung eines RT-Anwendung
Bevor wir mit der Planung anfangen, sollten wir folgende Fragen beantworten:
Warum erfordert diese Aufgabe ein Echtzeitsystem
Was sind die Echtzeitanforderungen
Wie schnell muss das System reagieren
Da es in diesem Fall um Menschenleben geht und die Folgen im Falle eines nicht fehlerfreien funktionsfähigen Systems, das System unbrauchbar wird und die Umwelt Schaden nimmt, spricht man hier von einem harten Realzeitsystem.
Zu den wichtigsten Elemente fürs System gehören:
Eine grafische Oberfläche zur Bedienung und Steuerung des Systems und zur Datenanzeige
Ein- und Ausgabeschnittstelle zur Gerätperipherie
Eingabesystem (in dem Fall eine spezielle Tastatur)
Datensicherung (auf einer Festplatte ...)
Netzwerkzugang(Optional) zur Fernsteuerung
Monitor Architektur
Beschreibung der Prozesse
Nach Systemsstart werden mehrere Prozesse gestartet und aktiviert. Diese Prozesse laufen parallel zueinander. Einige sind Applikationsspezifisch andre Systemspezifisch.
Applikationsspezifische Tasks:
Sensordaten einlesen
Datenanalyse
Graphische Darstellung
Überwachung der Grenzwerte (Sauerstoff & Puls)
Sauerstoffgerät steuern
Systemspezifische Tasks:
Dienstprogramme
Netzwerkdienste
Monitor Architektur 2
Monitor Architektur 3
(Wir folgen hier weitgehend wieder dem Skript von Herrn Houssaini)
Linux und Realzeit
Linux ist wie die meisten andren Betriebsysteme nicht für die Erfüllung von harten Realzeitsystembedienungen geeignet, Es kann auf Ereignisse nur in einem vordefinierten Zeitrahmen reagieren, aber das ist nicht immer der Fall. Es garantiert also nicht, dass ein Programm nach einer bestimmten Zeit Rechenzeit (CPU)erhält. Jedoch ist es möglich es zu modifizieren, so daß diese Einschränkung überwinden wird.
Einige Linux-Eigenschaften
Verführbarkeit des Quellcodes
Unterschtüzung fast aller verfügbaren Prozessplattformen
Minimales System zu erstellen (passt auf ein Diskette 1.44MB)
Embedded Tools (BusyBox....)
Lizenzfreie Software
Dynamisch Entwicklung im Internet
Um diese Realzeitbeschränkung von Linux auszugleichen, wurden RTLinux (Real Time Linux) und RTAI (Realtime Application Interface) entwicklt.
RTLinux:
RT-Linux wurde im Jahr 1997 am Department of Computer Science der Universität New Mexico als Forschungsprojekt entwickelt. RTLinux selbst ist zunächst ein kleiner Echtzeitkern, 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.
Es ist in zahlreichen Hochschulen und -Industrieprojekten benutzt worden.
1997 Erste Version von RTLinux Für Linux Kernel 2.0.25. Komplexes Hardware Interface. Philosophie: POSIX Kompatibilität. Patent geschützt (Jedoch frei für Forschung & Lehre)
RTAI:
1999 Erste Version von RTAI
Basierend auf RTLinux mit Linux Kernel 2.2.x
Einführung einer Abstraktionsebene: RTHAL-Kernel
Patch von nur 70 Zeilen
Philosophie: Minimale Kernel Änderungen
Entwickler-Orientierte API
Höhere Akzeptanz bei OS-Gemeinde
Die Linux Struktur:
Der Kern (Kernel) ist das Herz eines Linux Systems und hat folgende Aufgaben:
Prozeß-Scheduling
Prozeß-Kommunikation
Dateisystem verwalten
Ein-/Ausgabesteuerung
Gerätesteuerung (device driver)
Abwicklung von Interrupts und I/O-Operationen
Das Memory-Management des Betriebssystems sorgt dafür, dass Applikationsprogramme nur auf Speicherbereiche zugreifen können, die zu der Applikation gehören.
Linux Kernel 1
Linux Kernel 2
Linux Dateisystem
Der Bootvorgang für Linux System
Ein Linux System besteht hauptsichtlich aus drei Teile:
Boot Lader (Bootloader)
Linux Kernel
Root filesystem
Der Bootlader ist die Software, die direkt nach dem Start ausgeführt wird und hat die Aufgabe ein Betriebsystem im Speicher zu laden.
Als erstes wird der Kern gestartet. Er sorgt dafür, dass der Init-Prozess gestartet wird und initialisiert die Geräte.
In allen Übungen wird der Syslinux Boot Lader (von H. Peter Anvin)benutzt. Mit Syslinux kann ein Linux System von einer Diskette oder CD gestartet werden.
Neben syslinux gibt es eine Reihe von Bootlader: LILO, GRUB,ROLO(ROMed Linux Loader)
Bootstrapping mit Linux
Der Bootvorgang für Linux etwas ausführlicher
(für diese Darstellung siehe ausführlicher [BOVET 2003:Anhang A] sowie das gesamte Buch).
Bootstrap bezieht sich darauf, mindestens Teile eines Betriebssystems in ein System zu laden und diese zu starten.
Beim Einschalten des Computers wird ein spezieller Hardware-Reset ausgelöst, der die Werte von einigen Registern (z.B. cs und eip) auf feste Werte setzt, die es erlauben, aus fixierten (0xfffffff0) erste Startroutinen zu laden. Diese erste Startroutinen finden sich in speziellen ROM-Bausteinen, die als BIOS (Basic Input Output System) fungieren.
Die BIOS-Routinen werden in Real Mode ausgeführt. Im Real Mode bestehen die Adressen aus einem Segment seg und einem Offset off. Die zugehörige physikalische Adresse berechnet sich aus seg * 16 + off. Diese Addressierungsmethode ist sehr effizient, aber inflexibel.
Als erstes nimmt das BIOS ein POST vor (Power-On Self-test).
Alle Hardware-Geräte werden initialisiert und eine Liste aller installierten PCI-Geräten wird erstellt.
Es ird dann nach einer festgelegten Ordnung nach einem Datenträger gesucht, von dessen erstem Sektor (boot sector) ein Betriebssystem gebootet werden soll.
Sobald ein entsprechendes Gerät gefunden wird, wird der Inhalt des ersten Sektors ins RAM kopiert, beginnend bei Adresse 0x00007c00, dann wird diese Adresse angesprungen und die Befehle ab dieser Adresse werden ausgeführt.
In der Regel handelt es sich bei dem Programm, was als erstes aus dem boot sector geladen wird, um den sogenannten boot loader.
Im Falle eines Bootens von einer Floppy (Harddisk ist fast identisch) passiert bei Linux folgendes:
Zuerst wird der Kode von der Adresse 0x00007c00 zur Adresse 0x00090000 verschoben.
Dann wird der Real Mode stack ab Adresse 0x00003ff4 (waechst nach unten!) eingerichtet.
Die disk Parameter werden eingerichtet.
Dann wird die setup()-Routine von der Floppy ins RAM geladen ab 0x00090200
Dann wird der Rest des Kernels ins RAM geladen, entweder nach 0x00010000 (bei make zImage) oder nach 0x00100000 (bei make bzImage).
Dann springt das Programm zur Ausführung der Routine setup().
Die setup()-Routine initialisiert die gesamte Hardware nochmals, um so Portabilität zu gewährleisten:
Grösse des RAMs, Tastatur Wiederholungs- und Verzögerungsrate, Video Adapter, Plattenkontroller, IBM Micro channel Bus, PS/2-Zeigegerät, Advanced Power Management (APM)
Falls der Kernel in den Bereich ab 0x00010000 geladen worden war, wird er jetzt nach 0x00100000 verschoben.
Erstellt provisorisch IDT (Interrupt Descriptir Table) und GDT (Global Descriptor Table)
Reset der FPU
Umprogrammierung des PIC (Programmable Interrupt Controller): Verschieben der IRQs 0-15 (die die CPU für Ausnahmen benoetigt) nach 32-47.
Umschalten der CPU von Real Mode zu Protected Mode durch Setzen des PE Bit im cr0 Status Register. Gleichzeitig wird das PG bit im cr0 Register geöscht; Paging ist damit immer noch disabled.
Sprung zur startup_32()-Funktion.
Diese Routine richtet das Segmentations Register ein und einen provisorischen Stack.
Füllt bestimmte reservierte Bereiche (gekennzeichnet durch _edate und _end) mit Nullen.
Dann wird der Kernel dekomprimiert und zur Adresse 0x00100000 verschoben.
Sprung zur Adresse 0x00100000
Der Kernel beginnt mit einer weiteren Variante einer startup_32()-Funktion.
Initialisierung der Segment-Register mit den endgültigen Werten.
Der Kernel Modus Stack für process0 wird eingerichtet.
Initialisierung der provisorischen Kernel Page Tables.
Speichern der Adresse des Page Gloabel Directories im cr3 Register und Enabling Paging durch Setzen des PE bits in cr0.
Das bss-Segment des Kernels wird mit Nullen gefüllt.
Aufruf der setup_idt()-Funktion, um das IDT mit Null IRQ-Handler zu füllen.
Legt die System Parameter im ersten Page Frame ab.
Identifiziert das Modell der CPU.
Lädt die gdtr und idtr Register mit den Adressen von DDT und IDT-Tabellen.
Springt zur start_kernel()-Funktion.
Die start_kernel()-Funktion führt alle Initialisierungen zu Ende. Dabei wird abschliessend der Kernel thread für process 1 kreiert, der auch alle anderen Kernel Threads startet. Ausserdem führt dieser Kernel Thread das Programm /sbin/init aus.
Prozesse unter Linux(Task)
Definition eines Prozesses:
Ein Prozess ist ein Programm, das gemeinsam mit anderen Programmen von einem Computer unabhängig von einander ausgeführt wird. Prozesse können mehrere Zustände annehmen.
Multitasking:
Das Ziel der Multitasking ist die Auslastung der CPU zu erhöhen und wird dadurch bezeichnet, dass mehrere Prozesse gleichzeitig laufen können.
Arten von Tasks
periodisch (gleichmäßige Ankunftsintervalle, muß in der Regel vor nächstem Intervall abgearbeitet werden)
sporadisch (unregelmäßige Intervalle(asynchron), kann aber hard deadline haben)
aperiodisch (unregelmäßige Intervalle)
Taskzustände:
Prozesszustände
Fragen zum Beispiel von Herrn Houssaini:
Worin genau besteht das Realzeitsystem?
Was ist die Umgebung des Realzeitsystems?
Was sind die Ereignisse, die auf das System einwirken? Sind sie periodisch, sporadisch oder aperiodisch?
Wie lassen suich die zeitlichen Anforderungen für jedes einzelnes Ereignis hinsichtlich einer Deadline beschreiben?
Welches sind die verschiedenen Tasks, die durch die Ereignisse ausgelöst werden sollen?
Was sind die Prioritäten dieser Tasks?
Ist das System, auf dem die Tasks ausgeführt werden sollen präsemptiv oder nicht-präempiv?
Nach welchem Scheduling-Algorithmus sollen die Tasks verwaltet werden?
Fragen zu RTAI und Linux:
Was ist RTAI?
Welche Designmerkmale kennzeichnen RTAI bezüglich Realzeitverarbeitung?
Wie verhält sich RTAI zu Linux?
Was versteht man unter einem Bootstrap?
Welche Ereignisse werden in einem PC nach Betätigung des Resetschalters ausgelöst?
Was versteht man unter POST?
Was sind die wichtigsten Phasen der Bootroutine bei Linux ?
Was wird durch die Bootroutine bei Linux erreicht?
Was unterscheidet den User Mode vom Kernel Mode bei Linux?
Auf welche Weise kann die Aussenwelt den Kernelmode von Linux beeinflussen?
Was unterscheidet einen Prozess, der reentrant ist, von einem Prozess, der nicht reentrant ist?
Geht man von den Prozessen als Grundelementen des Linux-Kernels aus: welche Möglichkeiten bestehen aus Sicht des Kernels, Prozesse zu synchronisieren?
Wann benötigt man Warteschlagen für Prozesse?
Was ist der Unterschied zwischen einem präemptiven und einem nicht-präemptiven Kernel?