Multitasking ist durch den ATRI ST und den AMIGA als Schlagwort in aller Munde. Die Diskussion, was Multitasking eigentlich sei, dauert jedoch nach wie vor an: Wieviele parallelablaufende Programme oder welche anderen Merkmale kennzeichnen ein Multitasking-fĂ€higes Betriebssystem? Der zweite Teil der Ăberschrift möchte ein wenig provozieren: Denn daĂ Multitasking unter TOS einerseits und unter RTOS andererseits mehr als nur ein Buchstabe unterscheidet, soll dieser Beitrag zeigen.
PEARL (âProcess and Experiment Automation Real time Languageâ) ist eine Programmiersprache, die zu Beginn der 70er Jahre in Deutschland, unterstĂŒtzt durch die Bundesregierung, entwickelt wurde. In ihr sollten sich die Eigenschaften gĂ€ngiger Hochsprachen mit EchtzeitfĂ€higkeit und Multitasking paaren. ZunĂ€chst gab es nur fĂŒr groĂe Rechenanlagen Compiler; seit Anfang der 80er Jahre entstehen auch fĂŒr Mikrocomputer PEARL-Compiler. Ein âGeburtsortâ fĂŒr Compiler ist das Institut fĂŒr Regelungstechnik an der UniversitĂ€t Hannover. PEARL ist mit den angedeuteten Eigenschaften fĂŒr Regelungsaufgaben und ProzeĂautomatisierung geradezu prĂ€destiniert. NatĂŒrlich muĂ auch die Betriebssystemumgebung fĂŒr PEARL-Programme Echtzeit- und Multitasking-fĂ€hig sein. Deshalb wurde parallel RTOS/UH (âReal Time Operating System / UniversitĂ€t Hannoverâ) entwickelt, da die verfĂŒgbaren Betriebssysteme den Anforderungen nicht genĂŒgten.
Seit etwa 1984 werden RTOS/UH und der PEARL-Compiler auch auĂerhalb der UniversitĂ€t eingesetzt. In der Industrie laufen RTOS-Versionen fĂŒr verschiedenste VME-Bus- und andere Rechner, die auf dem 68000 basieren. Aber nicht nur in der industriellen Anwendung zeigt das Gespann seine StĂ€rken. Davon konnten sich zuerst die Anwender des cât 68000-Computers, seit Mitte 1986 aber auch die des ATARI ST ĂŒberzeugen. So erĂŒbrigen sich zum Beispiel Druckerspooler und Ramdisk aufgrund des Konzeptes von RTOS.
Diese Bemerkungen zur Geschichte mögen VerstĂ€ndnis dafĂŒr wecken, daĂ RTOS in 'mausigenâ Zeiten seine Befehle immer noch von der Tastatur erwartet. Wie die Maus unter RTOS trotzdem eingesetzt werden kann, habe ich im Rahmen einer Serie der Zeitschrift cât (siehe Literaturangaben) beschrieben. FĂŒr detailliertere Informationen verweise ich deshalb auf diese Serie. Ich beziehe mich hier auf den Update der ATARI-Version von RTOS, der gerade herausgekommen ist. Deshalb mag dem einen oder anderen Besitzer Ă€lterer RTOS-Versionen einiges neu Vorkommen. Dies sind jedoch nur Feinheiten: Das Grundkonzept ist fĂŒr alle RTOS-Versionen gleich.
Alles ereignisgesteuert
FĂŒr RTOS ist der Benutzer, der eine Taste drĂŒckt, ein Ereignis wie ein durch eine Lichtschranke ausgelöster Interrupt, ein abgelaufener Timer oder die Meldung, die die Tastatur des ATARI bei einer Mausbewegung sendet. Einzige Bedingung fĂŒr ein Ereignis unter RTOS ist, daĂ es fĂ€hig sein muĂ, sich mit einem Interrupt bemerkbar zu machen. Alle AktivitĂ€ten von RTOS kann man also als Reaktion auf Interrupte auffassen. Manche Interrupte werden dabei generell vom Betriebssystem abgefangen und von Systemtasks bedient, etwa die der Tastatur, der seriellen und parallelen Schnittstelle oder des Floppy-/DMA-Controllers; andere stehen dem Programmierer frei zur VerfĂŒgung. Beispiele hierfĂŒr sind der Bildsynchronisationsinterrupt und der Mausinterrupt.
MDDULE-SUMMARY:
TASKS:
(INT)Start (INT)Ende (INT)Rest (INT)Rechnen
VAR(RAM):0000-003F CODE(NO ROM):0040-0378
$0378 BYTES 0 ERRORS,
Bild 1
Solange zwischen zwei Ereignissen immer genĂŒgend Zeit fĂŒr die Reaktion bleibt, gibt es keine Probleme. Sobald dies nicht mehr der Fall ist, muĂ ein Ereignis auf die Bearbeitung warten. Auch RTOS kann den Prozessor nicht zerteilen, sondern lediglich die RechenkapazitĂ€t des Prozessors an verschiedene Aufgaben hintereinander vergeben. Der Unterschied zu anderen Betriebssystemen liegt darin, fĂŒr wieviele verschiedene Aufgaben die RechnerkapazitĂ€t verwaltet werden kann, wie schnell der Prozessor einer neuen Aufgabe zugeteilt wird und wieviel RechenkapazitĂ€t diese Verwaltung selber benötigt. So verwaltet RTOS so-viele Tasks, wie im Speicher Platz finden (das können durchaus mehr als 100 sein!), braucht als Reaktionszeit auf ProzeĂinterrupte unter PEARL keine 200 Mikrosekunden und schafft einen Taskwechselzyklus A-B-A in weniger als 400 Mikrosekunden (8 Mhz CPU, no waitstates, zum Beispiel ATARI ST).
Es bleibt zunĂ€chst die Frage, nach welchem Kriterium die ProzessorkapazitĂ€t zugeteilt wird, wenn mehrere Aufgaben gleichzeitig anstehen. Dazu hat jede Task eine PrioritĂ€t, die bei der Programmierung festgelegt wird, beim Aufruf aber noch geĂ€ndert werden kann. Generell kann man sagen, daĂ immer diejenige Task den Prozessor bekommt, die unter den lauffĂ€higen die höchste PrioritĂ€t hat. Dabei bedeutet LauffĂ€higkeit, daĂ eine Task aktiviert wurde und keiner der WartegrĂŒnde vorliegt. Ein anschauliches Beispiel fĂŒr einen Wartegrund liefert die Betreuungstask der seriellen Schnittstelle. Wenn ein Zeichen abgeschickt oder empfangen wurde, dauert es bei 9600 Baud etwa 1 Millisekunde, bis das nĂ€chste Zeichen an der Reihe ist. 1 Millisekunde ist aber fĂŒr einen schnellen Prozessor wie den 68000 sehr viel Zeit. Deshalb pausiert diese Task nach jedem Zeichen und gibt den Prozessor fĂŒr andere Tasks frei. Erst der nĂ€chste âReceive Data Register Fullâ- oder âTransmit Data Register Emptyâ-Interrupt aktiviert diese Task wieder. Im Gegensatz hierzu beschĂ€ftigen viele andere Betriebssysteme in dieser Situation den Prozessor vollstĂ€ndig damit, in einer Statusabfrageschleife zu kreisen, bis das nĂ€chste Zeichen gesendet oder empfangen werden kann.
Wenn auch die theoretische Betrachtung interessant sein mag, so möchte ich jetzt doch ein praktisches Programmbeispiel (Bild l) bringen, das die gegenseitige Steuerung von Tasks in PEARL demonstriert. Da RTOS als Unterlage fĂŒr PEARL-Programme entwickelt wurde, sind die Befehle fĂŒr Aktivierungen und Einplanungen auch auf Kommandoebene zu benutzen. Aber auch sonst lassen sich aus diesem PEARL-Beispiel viele RĂŒckschlĂŒsse auf die LeistungsfĂ€higkeit von RTOS ziehen.
Von der Kommandoebene aus wird die Task 'Startâ aktiviert. Sie teilt in Zeile 48 dem Betriebssystem mit, es möge doch bitte alle 50 Millisekunden die Task 'Rechnenâ aktivieren. AnschlieĂend startet sie in Zeile 49 die Task âRestâ. Diese beiden Tasks sind jetzt zwar lauffĂ€hig, belegen aber den Prozessor noch nicht, weil 'Startâ eine höhere PrioritĂ€t hat. Erst wenn 'Startâ in Zeile 50 fĂŒr zwei Sekunden pausiert, bekommt zuerst 'Rechnenâ und dann âRestâ den Prozessor. Sind die zwei Sekunden vergangen, wird 'Startâ vom Betriebssystem wieder âgewecktâ und teilt als letzte Aktion in Zeile 51 dem Betriebssystem noch mit, daĂ drei Sekunden nach diesem Befehl die Task 'Endeâ zu aktivieren ist. Danach hat 'Startâ seine Schuldigkeit getan.
Die Aufgabe von 'Startâ besteht also in der Hauptsache darin, die anderen drei Tasks termingerecht zu aktivieren und einzuplanen. Aber nicht nur in AbhĂ€ngigkeit von der Zeit können Aktivierungen und Einplanungen geschehen. Ebenso einfach kann dem Betriebssystem aufgetragen werden, eine Task als Reaktion auf einen Interrupt zu aktivieren. Meine oben erwĂ€hnte âMaus-Taskâ wird jeweils durch den Mausinterrupt aktiviert, liest die Meldung ĂŒber die Mausbewegung ein und bewegt entsprechend den Pfeil auf dem Bildschirm. Dabei sind keinerlei Hilfsroutinen in Assembler oder Eingriffe in das Betriebssystem notwendig, alles lĂ€Ăt sich ohne Kunstgriffe in PEARL programmieren.
Doch kommen wir zurĂŒck zu dem Moment, in dem 'Startâ pausiert legt und den Prozessor freigibt (Zeile 50). 'Rechnenâ und âRestâ sind nun beide lauffĂ€hig. Da 'Rechnenâ aber die höhere PrioritĂ€t hat, wird ihr der Prozessor zugeteilt. Erst wenn 'Rechnenâ fertig sit, bekommt auch âRestâ den Prozessor. âRestâ kann sich aber nicht lange des Prozessors erfreuen, denn nach 50 Millisekunden aktiviert RTOS wie befohlen wieder 'Rechnen' und entzieht ihr prioritĂ€tengerecht den Prozessor. Dieses Spiel wiederholt sich, bis 'Ende' den Kreislauf in den Zeilen 39 und 40 unterbricht. Ebenso einfach, wie in PEARL Tasks zu aktivieren und einzuplanen sind, können sie auch terminiert und ausgeplant werden.
In der Task 'Rest' zeigt sich ein weiterer grundlegender Unterschied zu anderen Betriebssystemen und Programmiersprachen. Eine Endlosschleife, sonst der Schrecken aller Programmierer, wird hier als probates Mittel der Programmierung eingesetzt. âRestâ hat die niedrigste PrioritĂ€t und bekommt somit den Prozessor nur dann, wenn keine andere Aufgabe mehr ansteht. Die Anzahl der SchleifendurchlĂ€ufe in âRestâ ist somit ein indirektes MaĂ fĂŒr die freie RechenkapazitĂ€t des Prozessors. Die Zahl von ĂŒber 220000 SchleifendurchlĂ€ufen innerhalb der 5 Sekunden, die 'Rest1 lĂ€uft, zeigt eindrucksvoll, wie wenig Zeit RTOS fĂŒr 100-mal 'Rechnenâ und die damit verbunden 200 Taskwechsel braucht.
»UH-PEARL-10.2 <c>1987 W.GERTH, HANNOVER
= 1 /*************************************************************/
= 2 /* */
= 3 /* Beispiel fuer gegenseitige Steuerung von Tasks in PEARL */
= 4 /* last update: 05.02.87 22hl0 */
= 5 /* */
= 6 /*************************************************************/
= 7
= 8 MODULE E:-:ample; /* Beginn der umfassenden Blockstruktur */
= 9
= 10 SYSTEM; /* Beschreibung der Betriebssystem-Umgebung--------------*/
= 11 Terminal: Al: /* Al: Datenstation der Terminalemulation */
= 12
= 13 PROBLEM: /* Beginn des Betriebssystem-unabhaengigen Teiles ----*/
= 14 /* SPeCify: Beschreibung der Eigenschaften einer Datenstation */
= 15 SPC Terminal DATION INOUT ALPHIC CONTROL(ALL);
= 16
= 17 /* DeCLare: Vereinbarung von Variablen -------------------*/
= 18 DCL X FLOAT; /* Rechenvariable */
= 19 DCL Leerlauf FIXED(31); /"* Zaehlvariable fuer Restzeit %/
= 20
= 21
= 22
= 23 Rechnen: TASK PRIQ 39: /*----------------------*/
= 24 DCL Y FLOAT; /* Diese Task gibt den Wert, den */
= 25 Y = 1 / X; /* Kehrwert sowie den Sinus von X */
= 26 PUT X, Y, SIN(X) TO Terminal BY F(5),(2)F(10.4),SKIP; /* */
= 27 X = X + 1.0: /* auf dem Bildschirm aus */
= 28 END; /* of task Rechnen ------------*/
= 29
= 30
= 31 Rest: TASK PRIO 40; /*---------------------------*/
= 32 REPEAT /* Beginn einer Endlosschleife */
= 33 â Leerlauf = Leerlauf + 1; /* incrementiere Leerlaufindex */
= 34 END; /* Ende der Endlosschleife */
= 35 END; /* of task Rest -----*/
= 36
= 37
= 38 Ende: TASK PPIO 39; /*------------------------*/
= 39 PREVENT Rechnen: /* nimm Rechnen aus zyklischer Einplanung*/
= 40 TERMINATE Rest: /* erloese Rest aus Endlosschleife */
= 41 PUT 'Leerlaufindex: '.Leerlauf TO Terminal BY SKIP, A, F(8). SKIP;
= 42 END; /* of task Ende------------------*/
= 43
= 44
= 45 Start: TASK PRIO 38; /*-----------------------*/
= 46 X = 1.0; /* initialisiere Rechenvariable */
= 47 Leerlauf = 0; /* initialisiere Leerlauf indes: */
= 48 ALL 0.05 SEC ACTIVATE Rechnen; /* plane Rechnen ein */
= 49 ACTIVATE Rest; /* starte Task Rest */
= 50 AFTER 2 SEC RESUME: /* warte 2 Sekunden */
= 51 AFTER 3 SEC ACTIVATE Ende; /* noch 3 Sekunden bis Ende */
= 52 END; /* of task Start ---------------------------------*/
= 53
= 54
= 55 MODEND: * of module E-ample *
Bei diesen Ăberlegungen ist die Zeit noch unberĂŒcksichtigt, die die Terminalemulation des ATARI benötigt. Auch unter RTOS muĂ jedes Zeichen als Pixelmuster auf den Bildschirm geschrieben werden. UnterdrĂŒckt man diese Arbeit, indem man die Ausgabe ĂŒber die serielle Schnittstelle an ein Terminal oder einen anderen Rechner umleitet, so wĂ€chst die Anzahl der SchleifendurchlĂ€ufe in 'Rest' auf ĂŒber 520 000, also mehr als 100 000 pro Sekunde an!
Nicht nur Multitasking sondern auch Multi-User
Nicht ganz ohne Absicht habe ich ein Terminal an der seriellen Schnittstelle erwĂ€hnt: Unter RTOS kann man den SpaĂ an einem ATARI auf bis zu drei Nutzer verteilen. Sowohl an die normale serielle Schnittstelle als auch an die MEDI-Schnittstelle kann ein Terminal angeschlossen werden, ĂŒber das man auf dem ATARI arbeiten kann. Bedingung fĂŒr das Terminal oder die Terminalemulation auf einem anderen Computer ist, daĂ es VT 52- oder Televideo-kompatibel sein muĂ. NatĂŒrlich stehen dem zweiten und dritten Nutzer nicht die GraphikfĂ€higkeiten der Terminalemulation des ersten Nutzers (siehe unten) zur VerfĂŒgung. Trotzdem eröffnen sich ungeahnte Möglichkeiten. So kann man den Freund, der ĂŒber ein Terminal oder einen Computer mit Terminalemulation verfĂŒgt, mittels Akustikkoppler oder Modem ebenso ohne Probleme als zweiten Nutzer anhĂ€n-gen, wie sich selbst, wenn man etwa noch den alten 8-Bitter, der nicht mehr genug leistete, stehen hat und ihn als Terminal 'miĂbrauchen' kann. Dann ergibt sich die interessante Möglichkeit, als Nutzer 1 ein Programm zu testen, wĂ€hrend man gleichzeitig als Nutzer 2 eventuell gefundene Fehler sofort im Programmtext korrigiert, ohne den Testlauf unterbrechen zu mĂŒssen.
Im Gegensatz zu UNIX oder Àhnlichen Mehrnutzer-Betriebssystemen schottet RTOS die einzelnen Nutzer nicht gegeneinander ab. So kann durchaus Nutzer 1 die Editortask, mit der
Nutzer 2 gerade an einem Programm schreibt, terminieren, worauf dieser âabgehĂ€ngtâ ist. Ein wesentlich ernsthafteres als dieses eher zwischenmenschliche Problem kann sich aber aus dem gleichzeitigen Zugriff auf eine Datei ergeben. Deshalb kann es sinnvoll sein, wenn man mit mehreren Nutzern auf einem Rechner arbeitet, in Rufweite zu bleiben und im Zweifelsfalle kurz zu fragen, ob einer der anderen Nutzer auch gerade an der be-
nötigten Datei arbeitet. Mn kann aber auch ĂŒber den Rechner die Frage an die anderen Terminals schicken und mittels Tastatur und Bildschirm miteinander kommunizieren.
LeistungsfÀhige Graphik
Wie schon angedeutet, unterstĂŒtzt die RTOS-Version fĂŒr den ATARI sowohl die Farbgraphik mit 640 x 200 Pixel als auch den monochromen Bildschirm mit 640 x 400 Pixel. FĂŒr den Programmierer stehen Funktionen fĂŒr Einzelpixel, Linie und Kreis zur VerfĂŒgung, Bildausschnitte können in BIT-Variablen kopiert, modifiziert und zurĂŒckkopiert werden. Die Auflösung des augenblicklich angeschlossenen Monitors kann im Programm ebenso abgefragt werden wie die Farbe eines jeden Pixels auf dem Bildschirm. Ein besonderes Feature von RTOS ist es, Bereiche fĂŒr mehrere zusĂ€tzliche Bilder im Speicher einrichten zu können. Sowohl von Programm- als auch von Kommandoebene aus kann bestimmt werden, welches der Bilder angezeigt werden soll. Auf diese Weise kann man Bildfolgen programmgesteuert auf dem Bildschirm erscheinen lassen. Jedes Programm kann festlegen, fĂŒr welches der Bilder die eigenen Graphikaufrufe bestimmt sind. Mehrere Tasks können also parallel an mehreren Graphiken arbeiten, ohne sich gegenseitig zu stören. Die auf Bild 2 dargestellte Graphik wurde mit niedriger PrioritĂ€t im Hintergrund berechnet, wĂ€hrend ich an einem anderen Programm arbeitete. Mit dem Hardcopy-Befehl wurde dann der Ausdruck erzeugt, ohne mein Programmieren zu stören.
Bleibt schlieĂlich zu klĂ€ren, weshalb weder Ramdisk noch Spooler gebraucht werden. Eine Ramdisk ist ĂŒberflĂŒssig, weil nicht nur mehrere Programme, sondern auch mehrere Dateien im RAM abgelegt werden können. Auch hier gilt nur die SpeichergröĂe als Grenze. Und ein Spooler erĂŒbrigt sich, weil das Ausdrucken nichts anderes ist als das Kopieren einer Datei in die Datenstation Drucker. Diesen Kopiervorgang betreut eine Task, die wie die oben beschriebene Betreuungstask der seriellen Schnittstelle WartezustĂ€nde hat und somit den Prozessor fĂŒr andere Aufgaben freigibt.
Literatur
[1] L. Frevert, Echtzeit-Praxis mit PEARL, B. G. Teubner Verlag, Stuttgart 1985
[2] Carl-Marcus Weitz, Echtzeit-Multitasking mit RTOS/ PEARL, ct 8/86 bis 3/87