Um mit einem Benutzer zu kommunizieren, also Eingaben zu empfangen oder Ausgaben zu machen, mu� eine Task an ein Terminal gekoppelt sein. Ein Terminal im Sinne von L3 ist eine Tastatur und ein Bildschirm, gleichg�ltig, ob �fest eingebaut� wie die CONSOLE oder �ber serielle Schnittstelle angeschlossen. Im System wird ein Terminal durch eine Terminaltask repr�sentiert, die drei Sohntasks hat. Eine dieser Sohntasks ist das Terminalmen�, die anderen beiden sind Manager f�r Tastatur und Bildschirm. Den Ausgangspunkt aller Zuordnungen eines Terminals an irgendwelche Tasks bildet die �Men�task�, die das Terminalmen� ausgibt. Diese Task, die ja aus Benutzersicht das Terminal darstellt, hei�t f�r die CONSOLE CONSOLE.term, f�r weitere Terminals dementsprechend ??.term.
Tastatur- und Bildschirmmanager sind im Grundzustand des Systems mit �ihrer� Men�task gekoppelt. Von dieser Task wird das Terminal an andere Tasks gekoppelt. �Eine Task an ein Terminal koppeln� bedeutet demzufolge, da� eine Zuordnung vorgenommen wird, die zur Folge hat, da� eine Task Botschaften vom Tastaturmanager erh�lt und Botschaften an den Bildschirmmanager absetzt. Die Regelung der Zuordnung von Terminals zu Tasks obliegt der Task SYSIO.
Ein Beschreibung der Botschaften zwischen Tasks und SYSIO findet sich in Kap.13.7.
SYSIO........................... 0:08:04 1 wait - T 2......................... 0:00:02 1 wait - T 2.term................ 0:00:00 1 wait "T 2" T 2.kbd................. 0:00:00 1 wait - T 2.dsp................. 0:00:01 1 wait - CONSOLE..................... 0:04:39 1 wait - CONSOLE.term............ 0:01:32 1 wait - CONSOLE.kbd............. 0:01:32 1 wait - CONSOLE.dsp............. 0:15:48 1 wait -
SYSIO f�hrt f�r jedes Terminal einen Terminalstack, auf dem zun�chst nur die Terminaltask eingetragen ist. Von der Terminaltask CONSOLE kommt nun ein Auftrag an SYSIO das Terminal an die Task OPERATOR zu koppeln, von der Terminaltask T 2 der Auftrag Pascal 5.5 anzukoppeln, von dort der Auftrag die Task PRINTER anzukoppeln (link(printer)). Intern stellt sich der Zustand der Taskstacks in SYSIO dann so dar:
Offensichtlich ist nach Abkoppeln von OPERATOR wieder die Terminaltask CONSOLE am Bildschirm sichtbar, nach Abkoppeln von PRINTER die Task PASCAL 5.5.
Das Erzeugen und Ankoppeln von Task kann durch Passworte �berwacht werden. Da Tasks autonom sind und das Passwort in der Task aufbewahrt wird, ist dieser Mechanismus hart. Wenn eine Task durch ein Passwort vor dem Ankoppeln gesch�tzt ist, l��t sich diese Task so lange nicht zum Dialog ankoppeln, bis ihr das korrekte Passwort eingegeben wurde. Wenn das Passwort richtig eingegeben wurde, wird die Task angekoppelt. Solange sie im Terminalstack des zugeordneten Terminals steht, ist keine erneute Eingabe des Passworts n�tig. Es ist also durchaus m�glich per HotKey via Terminalmen� in eine andere Task zu wechseln und anschlie�end wieder in die gesch�tzte Task zur�ckzukehren, ohne sich erneut zu identifizieren.
Die Zuordnung von Tasks und Terminals bleibt auch �ber Systemabschaltungen hinweg bestehen. Um zu verhindern, da� mit Passwort gesch�tzte Terminals nach Neustart des Systems (noch) einem Terminal zugeordnet sind, kann durch die Prozedur auto unlink erzwungen werden, da� die Task beim Neustart des Systems auf jeden Fall abgekoppelt ist.
BOOL PROC on line (TASK CONST task)
TASK PROC terminal task (TASK CONST task)
PROC auto unlink (BOOL CONST op):
Die Voreinstellung f�r alle Tasks ist auto unlink (FALSE).
BOOL PROC auto unlink (TASK CONST task)
PROC terminal inquiery (INT CONST timeout)
PACKET inq beispiel DEFINES bsp: PROC bsp: INT VAR i; FOR i FROM 1 UPTO 10 REP create (hex(i), dir) PER; { Die Prozedur macht irgendwas } terminal inquiry (never) { wartet dann auf ein Terminal } FOR i FROM 10 UPTO 15 REP putline(hex(i)) PER; { und dann macht sie was im dialog } monitor; END PROC bsp; END PACKET inq beispiel; {.. so sieht das in der aufrufenden Task aus, } { nachdem 'bsp' insertiert wurde } TASK VAR t; putline ("jetzt das begin"); begin ("son task 1", PROC bsp, t); { start, Sohntask legt Verzeichnisse an } terminal inquiry ; { ich will erstmal am Terminal bleiben } putline ("Sohntask angelegt..."); TEXT VAR tx := "......................" ; editget (tx); { Die Vatertask bleibt am Terminal } link (/"son task 1"); { jetzt Sohntask ankoppeln und } unlink; { selbst aus Terminalstack raus }
begin password (TEXT CONST old, new)
task password (TEXT CONST old, new)
Gerade f�r Aufgaben der Systemverwaltung ist es zweckm��ig, allen oder einzelnen Benutzern des Systems Nachrichten zukommen lassen zu k�nnen. terminal broadcast bietet die M�glichkeit einzelnen Tasks oder allen Benutzern Texte zu schicken, die tempor�r in einem passenden Fenster �ber dem aktuellen Bildschirminhalt ausgegeben werden. Durch Dr�cken der ESC Taste kann der Benutzer die Nachricht nach Durchlesen verschwinden lassen. Der Empfang solcher Nachrichten l��t sich pro Terminal einstellen. In der Voreinstellung sind f�r alle Terminals �die Nachrichten eingeschaltet�. Durch die Hotkey Tastenkombination:
Shift STRG ALT b Broadcast Ein/Ausschalten
l��t sich f�r jeden Arbeitsplatz einstellen, ob Nachrichten angezeigt werden sollen oder nicht. Falls der Empfang abgeschaltet ist, wird das im Terminalmen� angezeigt.
PROC terminal broadcast (TEXT CONST message, TASK CONST recv, INT CONST timeout)
PROC terminal broadcast (TEXT CONST message)
PROC setup terminal (TEXT CONST terminal name)
Es kann auch von Interesse sein, innerhalb eigener Programme Informationen �ber eine Terminaltask zu erhalten. Falls es beispielsweise n�tig ist, dem Benutzer eines bestimmten Terminals eine Mitteilung zu senden, so mu� zun�chst klar sein, welche Task an der Spitze des zu diesem Terminal geh�rigen Terminalstacks steht, um dann per terminal broadcast die Mitteilung an genau diese Task zu senden.
Der Inhalt eines Terminalstacks wird in Datenobjekte des Typs TASKARRAY verwaltet. Ein TASKARRAY ist eine Folge von TaskIDs (interne Taskbezeichner), die dynamisch verwaltet wird. Zu diesem Zweck ist die interne Repr�sentation nicht ROW xy TASK, sondern TEXT. Dieses ELAN Packet TASKARRAY ist auf der Diskette mit ELAN Beispielprogramme enthalten und sei jedem ELAN Interessenten w�rmstens empfohlen. Es ist nichttrivial, kurz und zeigt bestens, wie man unter L3 mit ELAN programmiert.
PROC get terminal stack (TASK CONST terminal, TASKARRAY VAR tarray)
TASKARRAY VAR terminal stack; TASK PROC terminal top (TASK CONST terminal) : get terminal stack (terminal, terminal stack); terminal stack SUB LENGTH terminal stack END PROC terminal top; put (name (terminal top (task ("CONSOLE"))));
Das Terminalmen� stellt die �u�erste Schicht des laufenden L3 Systems dar. Es wird durch die Men�task ausgegeben und kontrolliert. Diese Task ist im Normalfall Brudertask zu den Managern f�r Tastatur und Bildschirm. Um ein anderes Terminalmen� zu erhalten, mu� das standardm��ig angebotene entweder ersetzt oder �berlagert werden.
Eine vollst�ndige Ersetzung des Men�s kann dadurch erreicht werden, da� in der Task configurator eine Prozedur terminal menu insertiert wird. Wenn im configurator eine modifizierte Prozedur terminal menu insertiert ist, werden anschlie�end alle neuinstallierten Terminals mit diesem neuen Men� gestartet. Dieses Vorgehen erfordert eine Ersetzung der Task configurator. Die dazu n�tigen Aktionen sind am Ende dieses Abschnitts beschrieben.
Eine Alternative zu diesem Eingriff ins System ist die Erzeugung von Tasks mit modifiziertem Men� und die Zuordnung dieser Task als Men�task f�r ausgew�hlte Terminals. Zur Programmierung des Terminalmen�s sei an dieser Stelle auf das Standardmen� verwiesen, das auf der Diskette mit ELAN Beispielprogrammen enthalten ist.
Um den Terminaltasks neue Terminalmen�s zuzuordnen, sollte man im Systemzweig eine Task einrichten, unter der f�r alle Arbeitspl�tze, denen ein neues Men� zugeordnet werden soll, eine neue Men�task erzeugt wird. Diese Tasks werden dann dem jeweiligen Arbeitsplatz als neue Men�task zugeordnet, indem ein dementsprechender Auftrag an die Terminaltask geschickt wird. Im nachfolgenden Beispiel sei die Ausgangslage, da� in einer eigens daf�r erzeugten Task im Systemzweig eine passend gestaltete Prozedur special terminal menu insertiert wurde. Um die Terminaltask oli 1 mit diesem neuen Men� zu starten, sind folgende Aktionen n�tig:
PACKET change terminal menu DEFINES change terminal menu : LET terminal menu code = 0x 06 00 00 11; PROC change terminal menu (TASK CONST terminal) : TASK VAR menu; IF exists (terminal) THEN begin new terminal menu; send new terminal menu; ELSE errorstop ("Terminal existiert nicht"); FI; . begin new terminal menu : IF exists task (menu name) THEN end (task (menu name), quiet) FI; begin (menu name, PROC special terminal menu, menu); . menu name : name (terminal) + ".menu" . send new terminal menu : INT VAR reply; new msg; put msg (terminal menu code); put msg (menu); call manager (terminal, reply); END PROC change terminal menu; PROC special terminal menu : new menue { eigenes Terminalmen� } END PROC special terminal menu; END PACKET change terminal menu; change terminal menu (task ("oli 1"));
set up terminal ("oli 1"); { starten } change terminal menu (task ("oli 1")); { eigenes Men� installieren }
Austausch der Task configurator
Um das Terminalmen� auszutauschen, kann auch eine passende Task configurator, in der ein selbstgestaltetes Terminalmen� insertiert ist, in das System gebracht werden. Dazu mu� zun�chst eine neue Task als Sohntask von UTILITIES begonnen werden. In dieser neuen Task wird dann das neue Terminalmen� insertiert. Bei dieser Vorgehensweise mu� diese neue Prozedur terminal menu hei�en. Anschlie�end m�ssen alle Datenr�ume (Tastaturtabellen etc.) aus der Task configurator in die neue Task geholt werden. Anschlie�end wird die alte Task configurator gel�scht un in der neuen Task die Prozedur configuration manager aufgerufen. Diese benennt die Task in configurator um und startet das gewohnte Men�. Bei Benutzung des ersten Men�punkts terminal installieren wird f�r das neue Terminal das eigene, neue Terminalmen� gestartet.
begin ("conf", /"UTILITIES"); insert ("new terminal menu"); { die Datei enth�lt ein ELAN Packet, das eine neue Prozedur 'terminal menu' definiert } fetchall (/"configurator"); { Der configurator ist ein 'configuration manager'. Im Systemzweig kann man deshalb seine Managerfunktionen benutzen. } end (/"configurator"); { Da die neue Task 'conf' als Sohntask von UTILITIES Systemprivileg hat, kann man beliebige Tasks l�schen. configuration manager; { Die Task, die nun alle ben�tigten Tabellen enth�lt, wird zum neuen configurator }
Zum Betrieb von Modems, Druckern oder anderen Ger�ten, die �ber parallele oder serielle Schnittstelle an das L3 System angeschlossen werden sollen, gibt es Prozeduren zur Entwicklung eigener Treiberroutinen. Die Benutzung dieser Routinen erspart die �Low Level Programmierung� auf GDP (General Driver Protocol) Ebene.
Eine solche Treiberroutine besteht aus:
Ein Schnittstellenbaustein mit V24 oder CENTRONICS Ausgang ist im Sinne von L3 ein Ger�t. Wie ausf�hrlicher in Kapitel 13 dargestellt ist, werden Ger�te in einem L3 Systems durch besondere Tasks bedient. Diese Tasks sind Realprozesse, sie befinden sich permanent im Realspeicher und steuern die ihnen zugeordnete Hardware. Die Treibertasks finden sich im Taskbaum unterhalb der Task SYSHW. Aus historischen Gr�nden sind die Treiber f�r parallele Schnittstellen noch im Systemkern enthalten und werden erst in einer kommenden L3 Version als Tasks (= ladbare Treiber) realisiert. Es gibt jedoch Pseudonamen f�r die erste und zweite parallelen Schnittstelle, so da� sie wie Task angesprochen werden k�nnen. Sie lauten 'LPT1' bzw. 'LPT2'.
F�r serielle Schnittstellen gibt es zwei ladbare Treiber im System. F�r die integrierte
serielle Schnittstelle und weitere auf �unintelligenten Karten� eingebauten
Schnittstellen, gibt es die Task COM8250, f�r Schnittstellen auf �intelligenten
Karten� von DIGIBOARD , gibt es die DIGI Treiber. Da serielle Schnittstellen
bidirektional funktionieren, k�nnen mit einem Realprozess zwei Pseudonamen
assoziiert werden: 'COMx.out' als Ausgabetreibername und 'COMx.in' als
Eingabetreibername. 'x' ist dabei die Schnittstellennummer der angesprochenen
seriellen Schnittstelle. Falls Ausgabe- und Eingabetreiber auf der ersten seriellen
Schnittstelle (COM1) eingerichtet werden sollen, wird COM1 also durch die
Pseudonamen 'COM1.out' f�r den Ausgabetreiber und 'COM1.in' f�r den Eingabetreiber angesprochen. Entsprechend hei�en die Treiber f�r die Bausteine auf einer
intelligenten Karte 'DIGI1.in', 'DIGI1.out' usw.
PROC out driver(TEXT CONST out driver name)
PROC in driver(TEXT CONST in driver name)
PROC stream transfer (INT CONST baud, data bits, stop bits, parity)
Baudrate : 75, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
Datenbits: 7 oder 8
Stopbits : 0 , 1 oder 2
Parity : Zur Einstellung der gew�nschten Paritybits gibt es folgende Konstanten:
INT CONST no parity
INT CONST odd parity
INT CONST even parity
INT CONST high parity
INT CONST low parity
PROC dtr dsr flow control (BOOL CONST flag)
PROC rts cts flow control (BOOL CONST flag)
PROC xon xoff flow control (BOOL CONST flag)
PROC driver out (TEXT CONST string)
PROC driver out (TEXT CONST string, INT CONST from)
PROC driver out (TEXT CONST string, INT CONST from, to)
PROC driver out (TEXT CONST string address,string length)
PROC driver in (INT CONST timeout, TEXT VAR string)
PROC driver in (INT CONST timeout, string address, max string length, INT VAR string length)
FILE VAR file := sequential file (output, "protokoll"); in driver ("COM6.in"); out driver ("COM6.out"); stream transfer (9600, 8, 1, even parity); rts cts flow control (TRUE); open out driver ; TEXT VAR t := ""; REP driver in (1000, t) ; IF t <> "" THEN putline (t, file); t := ""; FI PER;