1 Einführung Echtzeitdatenverarbeitung 1 beinhaltet die Lösung von Aufgaben unter genauer Einhaltung vorgegebener zeitlicher Randbedingungen [9]. Typisches Beispiel ist die Aufgabe eines Roboterarms, Werkstücke von einem Montageband zu nehmen. Ein korrekter Ablauf ist weder bei verfrühtem noch bei verspätetem Zugriff möglich. Entsprechende Anforderungen gelten für zahlreiche Systeme, die im industriellen Umfeld, in Verkehrsmitteln oder im häuslichen Bereich in irgend einer Weise mit ihrer Umwelt interagieren. In der Regel müssen zeitlich parallel unter Berücksichtigung mehrerer Einflußgrößen mehrere Ausgangsgrößen eingestellt werden (Multitasking). Welche maximalen Zeitabweichungen bzw. Verzögerungen dabei zulässig sind, ohne daß das Systemverhalten fehlerhaft wird, hängt von der jeweiligen konkreten Aufgabenstellung ab (die Zeiten liegen oft im Millisekundenbereich). Für den Aufbau von Echtzeitsystemen werden alle Arten von Computern bis hin zu eingebetteten Systemen ( embedded control ) verwendet. Die notwendigen Betriebsprogramme können entweder alleinstehend laufen und müssen dann die gesamte Zeitsteuerung beinhalten oder können als Anwenderprogramme unter einem Echtzeitbetriebssystem dessen Einrichtungen zur Einhaltung von Zeitvorgaben nutzen. 2 Motivation Bei mehreren in Industriebetrieben durchgeführten Diplomarbeiten hat der Autor die Erfahrung gemacht, daß die Lösung von Echtzeitproblemen durch alleinstehende Assembler- oder C-Programme unverhältnismäßig lange Entwicklungszeiten bis zur Einhaltung des geforderten Zeitverhaltens zur Folge hatten und die notwendigen komplizierten Programmstrukturen nur schwer wartbar waren. 1 'Echtzeit' ist die übliche Übersetzung des englischen Wortes 'Realtime'. Echtzeitdatenverarbeitung JOCHEN SCHNEIDER Fachhochschule Hamburg, Fachbereich Elektrotechnik und Informatik Z.B. war es für die Realisierung einer mikrocontrollergesteuerten programmierbaren SPS- Fernsteuerung erforderlich, u.a. drei gleichzeitig aktive Schnittstellen zu bedienen [8]. Das Problem wurde durch Verschachteln von Instruktionsblöcken der drei Treiberprogramme gelöst (Funktionsprinzip siehe Bild 1). Bei der Programmentwicklung für den Ablauf unter einem Echtzeitbetriebssystem ist die Strukturierung erheblich einfacher, es entstehen betriebssicherere Systeme und Modifikation und Wartung sind mit weniger Problemen verbunden. Welche grundlegenden Eigenschaften von Echtzeitbetriebssystemen diese Vereinfachungen bewirken, soll der vorliegende Beitrag aufzeigen. 3 Eigenschaften von Echtzeitbetriebssystemen Dem Entwickler bietet sich die Auswahl unter mehr als 80 unterschiedlichen Echtzeitbetriebssystemen [1]. Viele sind nur für eine bestimmte Prozessorfamilie geeignet, andere für zahlreiche unterschiedliche Prozessortypen verfügbar. Es gibt keinen häufig eingesetzten Prof. Dr. JOCHEN SCHNEIDER FH Hamburg Fachbereich E/I Berliner Tor 3 20099 Hamburg TEL.: 040 2488-2688 FAX: 040 248458-88 E-MAIL: schneider@ etech.fh-hamburg.de Bild 1: Multitasking eines alleinstehenden Bedienprogramms für drei Schnittstellen durch Verschachteln von Instruktionsblöcken dreier separater Treiberprogramme [11]
Bild 2: Beispiel zur Rechenzeitzuteilung. Die Prozesse A bis F befinden sich im Zustand bereit. Wegen der unterschiedlichen Prioritäten werden aber nur die Prozesse A bis C wechselweise aktiviert. Priorität Mikroprozessor bzw. Mikrocontroller, für den kein Echtzeitbetriebssystem verfügbar ist. Die Kommandosprachen sind überwiegend von UNIX abgeleitet. Mit unterschiedlichsten grafischen Oberflächen lassen sich Benutzerschnittstellen für Anwendungen vom eingebetteten System mit kleiner LCD-Anzeige bis zum Rechner mit Großbildschirm realisieren. Die Programmierschnittstellen genügen vielfach der amerikanischen Norm POSIX 2 1003.1b. (Eine gute Einführung findet man in [4].) Die Stückpreise von Echtzeitbetriebssystemen liegen zwischen kostenlos bis über DM 10 000. Gemeinsame elementare Eigenschaften sind Multitasking, Einrichtungen zur Steuerung des Zeitverhaltens, Methoden zur Ressourcenzuteilung und schnelle Kommunikationsmechanismen. 3.1 Threads, Prozesse Ein Prozessor stellt i.a. nur einen Controllerkern zur Verfügung, so daß die parallelen Prozesse aus Sicht des Prozessors zeitseriell ablaufen müssen (quasiparallele Abarbeitung der Aufgaben). Die Forderung läßt sich auf zwei verschiedene Weisen realisieren. Zum einen durch nebenläufige Unterprogramme (Threads), die zeitlich abwechselnd in einem gemeinsamen Speicherbereich ausgeführt werden und zum anderen durch die Einrichtung einer kompletten virtuellen Maschine für jeden parallel ablaufenden Programmteil (). 2 'POSIX' ist die Kurzbezeichnung für 'Portable Operating System Interface'. Warteschlange der Prozesse im Zustand 'bereit' 31 10 5 0 aktiv A D E B F C G wartend Z In beiden Fällen erledigt der Scheduler, ein zentraler Teil des Betriebssystems, die Prozessorzuteilung. Wenn der verwendete Prozessor über eine Speicherverwaltungseinheit verfügt, wird in der Regel vorzugsweise das konzept angewandt, da sich Programmfehler bei kaum unterschiedlichem Zeitbedarf für die Kontextumschaltung nicht auf die parallel ablaufenden Programmteile auswirken können. Zudem hat eine Strukturierung in Prozesse den Vorteil, daß bei Performanceproblemen unter der Voraussetzung einer entsprechenden Unterstützung des Betriebssystems ohne prinzipielle Programmänderungen leicht auf ein vernetztes Multiprozessorsystem übergegangen werden kann. Z.B. kann man in einem Meßdatenerfassungssystem einen rechenintensiven Auswerteprozeß auf einen anderen Prozessor auslagern. Die Generierung und das Beenden von Prozessen ist durch entsprechende Betriebssystemaufrufe während der Laufzeit eines Programms möglich. Bei Vorhandensein von genügend Speicherplatz und ausreichenden Systemressourcen können in einem Echtzeitsystem durchaus mehrere hundert Prozesse und/ oder Threads parallel ablaufen. Einige Echtzeitbetriebssysteme sind auch intern in Prozesse strukturiert, so daß insbesondere Treiber für Peripheriegeräte ohne Systemneustart dynamisch hinzugefügt oder entfernt werden können. Die jeweils rechtzeitige Prozessorzuteilung an die einzelnen Prozesse ist nicht immer einfach lösbar. Ein Echtzeitbetriebssystem ordnet dazu jedem einen Zustand und eine individuell einstellbare Priorität zu. Die wichtigsten Zustände sind aktiv, wartend und bereit. Der Zustand aktiv charakterisiert einen, der gerade den Prozessor beansprucht. Ein, der auf Daten von einem Peripheriegerät wartet oder erst zu einem späteren Zeitpunkt aktiviert werden soll, ist im Zustand wartend und ein, der bei Verfügbarkeit der notwendigen Ressourcen weiterlaufen kann, befindet sich im Zustand bereit. 3.2 Zeitsteuerung Der Scheduler versetzt jeweils den höchstpriorisierten vom Zustand bereit in den Zustand aktiv. Die aktivierte virtuelle Maschine belegt den Prozessorkern dann für die Dauer einer Zeitscheibe (z.b. 50 ms). Wenn zwischenzeitlich ein noch höher priorisierter in den Zustand bereit wechselt, löst dieser eine Umschaltung durch den Scheduler aus und belegt seinerseits den Prozessor (siehe Bild 2). Prinzipbedingt könnte ein höchstpriorisierter demnach beliebig lange im Zustand aktiv verbleiben und damit alle anderen Echtzeitaktionen verhindern. Hohe Prioritäten dürfen deshalb ausschließlich an kurze zeitkritische Aufgaben wie die Übernahme von Peripheriedaten vergeben werden, und längere Berechnungen müssen mit möglichst niedriger Priorität ausgeführt werden. [12]
Falls mehrere Prozesse mit der gleichen höchsten Priorität den Zustand bereit einnehmen, kann der Scheduler unterschiedlich (i.a. einstellbar) reagieren. Z.B. können die einzelnen Prozesse abwechselnd nacheinander für jeweils eine Zeitscheibe aktiviert werden oder bis zu einem selbständigen Wechsel in den Zustand wartend durchlaufen. Für das zeitgesteuerte Starten von Threads oder Prozessen stehen in Echtzeitbetriebssystemen Timer zur Verfügung. Das sind spezialisierte Prozesse, die zu absolut oder relativ vorwählbaren Zeiten vom Scheduler aktiviert werden, um z.b. den Zustand eines zu steuernden anderen Prozesses von wartend auf bereit zu ändern. Die erreichbaren zeitlichen Auflösungen und Genauigkeiten hängen i.w. von den Möglichkeiten der verwendeten Hardware ab und liegen typischerweise im Mikro- bis Millisekundenbereich. Zur schnellen Reaktion auf externe Ereignisse unterstützen alle Echtzeitbetriebssysteme Hardwareinterrupts. Diese sind immer höher priorisiert als Threads und Prozesse; der Scheduler hat auf den Ablauf eines Interrupthandlers keinen Einfluß (siehe Bild 3). Auch die Priorisierung unterschiedlicher Interrupts zueinander ist (teilweise programmierbar) durch die Hardwarefunktionen des verwendeten Prozessors vorgegeben. Genau vorhersagbar ist das Zeitverhalten nur für den höchstpriorisierten Interrupt (siehe Bild 4). Üblicherweise stellt ein Echtzeitbetriebssystem für alle möglichen Interrupts bereits vorbereitete Handler mit allen Sicherungs- und Restaurierungsoperationen für den unterbrochenen Programmteil zur Verfügung, so daß durch entsprechende Betriebssystemaufrufe lediglich die vorgesehenen Benutzeraktionen eingefügt werden müssen. Um das vom Scheduler festgelegte Zeitverhalten nicht zu stören, müssen alle Interrupthandler möglichst schnell wieder beendet werden. Dazu läßt sich nach evtl. notwendigen Hardwareaktionen ein entsprechend vorbereiteter vom Zustand wartend in den Zustand bereit versetzen, um dann schedulergesteuert alle weiteren Datenverarbeitungsschritte durchzuführen. Die vom Auftreten des Interruptsignals bis zur Ausführung des ersten Befehls im Interrupthandler maximal benötigte Zeit (Interruptlatenz) gehört zu den wichtigsten Kennwerten eines Echtzeitbetriebssystems. 3.3 Kommunikationsmechanismen Der zur Ausnutzung der zeitlichen Steuermöglichkeiten notwendige modulare Programmaufbau ist nur möglich, wenn die einzelnen Prozesse auf effiziente Weise Daten austauschen können. Da die einzelnen Module bei Realisierung als virtuelle Maschinen Interrupt tritt auf Interrupthandler startet Interrupthandler ist fertig durch die Speicherverwaltungseinheit streng voneinander abgeschirmt sind, kann eine Übergabe von Daten als Funktionsparameter oder als globale Variablen nicht funktionieren. Statt dessen muß das Betriebssystem für den Transport der Daten von zu sorgen. Viele Betriebssysteme bieten dafür mehrere Realisierungsmöglichkeiten: Die wichtigste Übertragungsmethode ist das Message Passing. Dazu muß der sendende die Daten unter Angabe der gewünschten Übertragungspriorität an das Betriebssystem übergeben. Die Daten werden dann in einer nach Prioritäten und Ankunftszeiten geordneten Warteschlange aufbewahrt, bis sie vom Zielprozeß abgerufen werden. Aufgrund des Multitaskings kann es vorkommen, daß das Abrufen einer Nachricht zeitlich vor dem Absenden erfolgt. In diesem Fall wird der Empfangsprozeß vom Scheduler in den ressourcenschonenden Zustand wartend versetzt, bis die Nachricht eintrifft. Unter Ausnutzung dieser Funktionsweise ist auch eine zeitliche Synchronisation der Aktivitäten zweier oder mehrerer Prozesse möglich. Die beim Message Passing erreichbaren Übertragungsgeschwindigkeiten sind von den Möglichkeiten der Hardware und der Art der Implementierung abhängig (zwischen einigen KB/s bis zu mehreren MB/s). Häufig wird auch die Möglichkeit der Festlegung gemeinsamer Speicherbereiche ( shared memory ) angeboten. Ob diese durch entsprechende Programmierung der Speicherverwaltungseinheit oder durch transparente Anwendung des Message Passing realisiert wer- A Int X T T T il int iret IRQ X IntY IRQ Y B unterbrochener läuft weiter C Zeit Bild 3: Zeitverhalten beim Auftreten eines Interrupts. T il ist die Interruptlatenzzeit, T int die Ausführungszeit des Handlers und T iret die Rückkehrzeit Bild 4: Beispiel zum Zeitverhalten während der Unterbrechung eines Interrupts IRQ X (mit Handler Int X ) durch einen höher priorisierten Interrupt IRQ Y (mit Handler Int Y ). Int Y versetzt B in den Zustand bereit, Int X C. Zeit [13]
Tabelle 1: Kennwerte des Echtzeitbetriebssystems QNX bei Verwendung auf einem Pentium/90 PC den, ist je nach Betriebssystem unterschiedlich. Ein so durchgeführter Datenaustausch erscheint zunächst besonders attraktiv, da besondere Betriebssystemaufrufe nicht erforderlich sind. Allerdings muß man bedenken, daß die einzelnen Prozesse ja zeitlich parallel abgearbeitet werden und deshalb geeignete Synchronisationsmaßnahmen getroffen werden müssen. Schließlich muß sowohl der Empfangsprozeß wissen, wann Daten abholbereit zur Verfügung stehen als auch der Sendeprozeß, wann neue Daten geliefert werden können. 3.4 Ressourcenzuteilung Für die Zugriffssteuerung auf gemeinsam benutzte Speicherbereiche und andere Ressourcen können Semaphore eingesetzt werden. Wenn ein auf eine so verwaltete Ressource zugreifen möchte, muß er mittels eines Betriebssystemaufrufs zunächst eine Anforderung an das Semaphor senden. Falls die Ressource gerade anderweitig benutzt wird, geht der in den Zustand wartend, bis sich unter den wartenden Prozessen keiner mit höherer Priorität mehr befindet. Es erfolgt dann ein Wechsel in den Zustand bereit und nach Aktivierung durch den Scheduler kann der Zugriff erfolgen. Danach muß die Ressource durch einen weiteren Betriebssystemaufruf an das Semaphor wieder freigegeben werden. Bei häufig verwendeten Peripheriegeräten kann es sich lohnen, die Ressourcenverwaltung auf einen gesonderten Serverprozeß zu verlagern, der z.b. via Message Passing Anfragen entgegennimmt und alle Datenübertragungen realisiert. Durch Puffern mehrfach benötigter Datenbereiche durch den Serverprozeß läßt sich die Arbeitsgeschwindigkeit eines Systems ggf. erheblich steigern. Für Standardperipheriegeräte und gebräuchliche Schnittstellen liefern die Hersteller von Echtzeitbetriebssystemen i.a. entsprechend optimierte Treiberprogramme bereits mit. Der für die Anpassung spezieller Peripherie zu treibende Aufwand ist je nach Systemarchitektur sehr unterschiedlich. Er muß bei der Bewertung der Eignung eines Betriebssystems sorgfältig geprüft werden. Kontextumschaltung: 28 µs Interruptlatenz: 5 µs Timerauflösung: Übertragungsrate bei Message Passing: bis 100 µs (einstellbar, ohne Hardwarezusatz) 35 MB/s (bei 4096 Byte großen Datenpaketen) 4 Anwendungen Neben der Zusammenarbeit mit Industriefirmen wurde inzwischen im Lehrgebiet Digitale Informationstechnik die Vermittlung von Echtzeitdatenverarbeitung in den Studienplan der Studenten aufgenommen. Aufgrund von guten Erfahrungen des Autors während seiner industriellen Entwicklertätigkeit mit dem PC-Echtzeitbetriebssystem QNX (s. Tabelle 1) wurde dieses für das Labor für Digitale Schaltungstechnik in mehreren Exemplaren angeschafft und seither u.a. für diverse Diplom- und Studienarbeiten erfolgreich eingesetzt. QNX [5] ist modular aufgebaut und beinhaltet einen nur wenige Kilobyte großen Betriebssystemkern. Der Einsatz ist auf allen Varianten von PC-Hardware sowie auf Power-PCund MIPS-Prozessoren möglich. Schnittstellenund Gerätetreiber laufen als Benutzerprozesse und können während des Betriebs jederzeit hinzugefügt oder entfernt werden. Drei verschiedene grafische Benutzeroberflächen erlauben die Ansteuerung unterschiedlichster Hardwarekonfigurationen. Durch ein transparentes Vernetzungskonzept werden auch Multiprozessorsysteme problemlos unterstützt. Eine Einführung in die Echtzeitdatenverarbeitung mit QNX findet man in [6]. Tabelle 1 zeigt einige mit einem Pentium/90 ermittelte Betriebssystemkennwerte. Umfangreichere konkrete Anwendungen von QNX wurden bisher vorwiegend im Rahmen des Entwicklungsprojekts Hard- und Software für Koordinatenmeßgeräte erstellt. Eine grundlegende Beschreibung findet man in [7], Erweiterungen des Konzepts wurden u.a. in [3] und [2] entwickelt. Für den Einsatz in einem eingebetteten System wird QNX z.zt. im Rahmen einer noch nicht ganz abgeschlossenen Diplomarbeit in das Flash-ROM eines vernetzten PC104 Mikrocomputers implementiert. Zur komfortablen Benutzerkommunikation soll die echtzeitgeeignete grafische Oberfläche Photon angepaßt werden, so daß nach Fertigstellung ein eigenständiges leistungsfähiges Echtzeitsystem für Steuerung und Meßdatenerfassung auf kleinstem Raum zur Verfügung steht. 5 Fazit Echtzeitbetriebssysteme stellen die für die genaue Einhaltung eines vorgegebenen Zeitverhaltens notwendigen Hilfsmittel zur Verfügung. Durch ihre Anwendung läßt sich die Entwicklung von Echtzeitsystemen vereinfachen und beschleunigen. Der erzwungene modulare Programmaufbau führt zu erhöhter Betriebssicherheit und erleichtert die spätere Systemwartung. Die zusätzlichen Anschaffungskosten [14]
für das Betriebssystem fallen auch bei kleinen Projekten gegenüber den Vorteilen kaum ins Gewicht. Entsprechende Kenntnisse und Erfahrungen der Systementwickler zu fördern lohnt sich. Literatur [1] Auswahlliste für Echtzeitbetriebssysteme: http://www.realtime-info.be/encyc/market/rtos/rtos.htm. [2] Bläske O.: Entwicklung eines Interpreters für spezielle SPS-Syntax zur Steuerung von Koordinatenmeßgeräten unter Verwendung der UNIX-Werkzeuge lex und yacc. Diplomarbeit, FH Hamburg, FB E/I, 1997. [3] Bruse I., Krüger J.: Entwicklung eines Interpreters für spezielle SPS-Syntax zur Steuerung von Koordinatenmeßgeräten. Diplomarbeit, FH Hamburg, FB E/I, 1995. [4] Gallmeister B.O.: POSIX.4-Programming for the Real World. O Reilly & Associates Inc., 1995. [5] QNX Software Systems Ltd.: QNX 4 Operating System System Architecture. Kanata, 1997. Auch: http://www.qnx.com / literature/qnx_sysarch/. [6] Schneider J.: Echtzeit-Datenverarbeitung. Studienskript, FH Hamburg FB E/I, 1997. [7] Schubert F.: Parallele Prozessoren steuern Koordinatenmeßmaschine. Technische Berichte Nr. 27, pp. 11-17, FH Hamburg, FB E/I, 1994. [8] Schulenburg J.: Entwicklung eines programmierbaren mikrocontrollergesteuerten Moduls zur Fernsteuerung einer SI- MATIC S5 über das EURO-ISDN. Diplomarbeit, FH Hamburg FB E/I, 1996. [9] Uhres L.: comp.realtime Frequently Asked Questions. http://www.faqs.org /faqs/ realtime-computing/faq/. [15]