Seminar Seminar Echzeitverarbeitung Abkürzungen 0 Abkürzungen ................................................................................................................................3 1 Praktikum zur Zeitvarianz ...........................................................................................................3 2 Realisierung eines wechselseitigen Ausschluß ...........................................................................5 3 Nachrichtenaustausch .................................................................................................................6 3.1 Problemanalyse:................................................................................................................................ 6 3.1.1 3.1.2 3.2 Ablauf der Kommunikation:.......................................................................................................................6 Erforderliche Variablen: .............................................................................................................................6 Algorithmen ...................................................................................................................................... 8 Abbildung 1-1; Zählender Hintergrundprozeß - ungeschützt______________________________________________ 3 Abbildung 1-2; Interuptserviceroutine des Hintergrundprozess ___________________________________________ 3 Abbildung 2-1; Hintergrundprozeß mit Semaphor______________________________________________________ 5 Abbildung 2-2; Gesicherte ISR_____________________________________________________________________ 5 Abbildung 3-1; Beispiel Nachrichtenaustausch - Hintergrundprogrammalgorithmus __________________________ 8 Abbildung 3-3; ISR zur Demonstration eines gepufferten Nachrichtenaustauschs _____________________________ 8 Zeitvarianz der Ergebnisse abhängiger paralleler Rechenprozesse:________________________________________ 4 Realisierung eines wechselseitigen Ausschluß zur Beseitigung der Zeitvarianz:_______________________________ 5 Praktikum zum Nachrichtenaustausch zwischen abhängigen parallelen Prozessen - ISR________________________ 8 Praktikum zum Nachrichtenaustausch zwischen abhängigen parallelen Prozessen - Code für dynamisches Warten/ dynamische Blockade von Prozess k ________________________________________________________________ 8 Beispiel eines Alarms mit dem MRT86______________________________________________________________ 10 Isabel Maine C. Drost Seite 2 von 16 0 1 Abkürzungen Praktikum zur Zeitvarianz Es ist ein C-Programm zu entwickeln, das 2 Prozesse A und B realisiert, die das Auftreten zweier verschiedener Ereignisse in je einer lokalen sowie einer globalen Variablen zählen. Ereignisse des Prozesses A sollen in größeren Zeitabständen (z.B. 3sec) und Ereignisse des Prozesses B durch Tastaturbetätigung simuliert werden. Prozess A als zeitgesteuerte Programmschleife realisieren, die durch Betätigen der Enter-Taste abgebrochen wird. Prozess B als Tastatur-ISR realisieren (Reaktion auf Loslassen der Taste) Æ Umlenkung des Tastaturinterupts unter M$Dos Prozeß A (Hintergrundprozeß) i=0 (durch A und B gemeinsam ermittelte Ereigniszahl) a=0 (durch A ermittelte Ereignisanzahl) b=0 (durch B ermittelte Ereignisanzahl) Tastatur - ISR - Adresse (Vektor 9) retten (z.B. in alttaste) #include <dos.h> Prozess B (Tastatur - ISR) - Als ISR gekennzeichnete Fkt. taste code=inportb (60 H) j code >=80h? i++ (globale Ereignisse) Interrupt 9 auf Funktion taste umlenken hilf=i Verzögerung um 1s b++ (lokale Ereignisse) outportb (20H, 20H) hilf++ Verzögerung um 1s i=hilf Verzögerung um 1s a++ Anzeige von i, a, b, a+b-i solange code!=156 (Code für losgelassene Entertaste) Tastatur - ISR zurückstellen (alttaste) Abbildung 1-1; Zählender Hintergrundprozeß ungeschützt Abbildung 1-2; Interuptserviceroutine des Hintergrundprozess n Seminar Echzeitverarbeitung Praktikum zur Zeitvarianz Zeitvarianz der Ergebnisse abhängiger paralleler Rechenprozesse: /*Zeitvarianz der Ergebnisse abhängiger paralleler Rechenprozesse*/ #include <stdio.h> #include <conio.h> #include <dos.h> unsigned int i, a, b; unsigned char code=0; void interupt(*alttaste)(void); void interupt taste(void); { code=inportb(0x60); if(code>=0x80) { i++; b++; } outportb(0x20, 0x20); } void main(void) { unsigned int hilf; alttaste=getvect(9); setvect(9, taste); do { hilf=i; delay(1000); /** * bei sleep wird der Prozessor abgegeben, hier bleibt er beim Programm – * vermeidet Ärger **/ hilf++; delay(1000); i=hilf; delay(1000); a++; ... } while(code!=156) setvect(9, alttaste); } Isabel Maine C. Drost Seite 4 von 16 2 Realisierung eines wechselseitigen Ausschluß Realisierung eines wechselseitigen Ausschluß zur Beseitigung der Zeitvarianz: • • • Schließe aus, dass während des Veränderns der Variablen in der Hauptschleife ein Interrupt ausgelöst wird Setze einen Semaphor auf die zu verändernde Variable (zu favourisierende Möglichkeit) Setze keinen delay in die ISR, um auf den Semaphor zu warten – Deadlockmöglichkeit – zähle auf einer anderen Variablen als i weiter und addiere die dann zu i, wenn Du wieder darfst. #include <dos.h> Prozess B (Tastatur - ISR) - Als ISR gekennzeichnete Fkt. taste code=inportb (60 H) Prozeß A (Hintergrundprozeß) i=0 (durch A und B gemeinsam ermittelte Ereigniszahl) a=0 (durch A ermittelte Ereignisanzahl) code >=80h? j b=0 (durch B ermittelte Ereignisanzahl) sema=0 (Semaphor initialisieren) j sema=1? ihilf=0 ihilf++ i++ Tastatur - ISR - Adresse (Vektor 9) retten (z.B. in alttaste) b++ Interrupt 9 auf Funktion taste umlenken outportb (20H, 20H) ihilf=0 Abbildung 2-2; Gesicherte ISR sema=1 hilf=i Verzögerung um 1s hilf++ Verzögerung um 1s i=hilf Verzögerung um 1s a++ Anzeige von i, a, b, a+b-i Prozessor - Interupt - Sperre (CLI) sema=0 i=i+ihilf Prozessor - Interupt - freigeben (sti) solange code!=156 (Code für losgelassene Entertaste) Tastatur - ISR zurückstellen (alttaste) Nur Prozeß A kann sema verändern, die ISR liest es nur! Abbildung Semaphor 2-1; Hintergrundprozeß mit n n Seminar Echzeitverarbeitung Nachrichtenaustausch 3 Nachrichtenaustausch Praktikum zum Nachrichtenaustausch zwischen abhängigen parallelen Prozessen • C-Programm zum Nachrichtenaustausch mit Pufferung einer Nachrichteneinheit zwischen Sender und Empfänger • Produzenten- / Konsumentenverhältnis • der Produzent (Prozess_P) ist als Tastatur-ISR zu realisieren • der Konsument (Prozess_K) ist als Hintergrundprogramm zu realisieren 3.1 Problemanalyse 3.1.1 • • • • • • • • • Ablauf der Kommunikation: Prozess_P erwartet einen Tastaturinterupt er überprüft, ob der Nachrichtenpuffer voll ist ist das der Fall, wird der Prozeß_p blockiert andernfalls wird der Tastaturcode eingegeben, in den Nachrichtenpuffer geschrieben und getestet, ob Prozess_k bereits auf Nachricht wartet ist das der Fall, wird die Nachricht wieder aus dem Puffer entnommen, in den lokalen Bereich von Prozess_k übertrgen und Prozess_k deblockiert Prozess_k testet, ob eine Nachricht für ihn eingetroffen ist (Test erfolgt über Semaphor, der Zugriff auf den Nachrichtenpuffer bestimmt) ist das nicht der Fall, wird er blockiert andernfalls wird die Nachricht aus dem Puffer entnommen, in den lokalen Bereich von Prozess_k übertragen und getestet, ob Prozess_p bereits auf Pufferentleerung wartet ist das der Fall, wird der Tastencode in den Nachrichtenpuffer geschrieben und Prozess_p deblockiert 3.1.2 Erforderliche Variablen: x – lokale Größe, die den eingegebenen Tastencode enthält, keine Speichervariable, Tastatureingbekanal 60H y – lokale Größe in Prozess_k (empfangenes Tastaturzeichen) p – globale Bytegröße, in der das gepufferte Zeichen/ Nachricht steht s – globale Integergröße, die als Semaphor zur Verwaltung des Nachrichtenpuffers dient Belegung von s: Initialisierung mit 0 – Nachrichtenpuffer ist leer trifft ein Empfänger auf einen Nachrichtenpuffer, wird s dekrementiert: –1 – Empfänger wartet auf Nachricht 1 – Nachrichtenpuffer ist voll 2 – Sender (Prozess_P) wartet auf Pufferentleerung ... void interrupt Prozess_P(void) { outportb(0x20, 0x20); s++; if(s>1) ; /* nichtlesen des Zeichen entspricht Blockade (Zeichenübergabe läuft an **sich über Handshakeverfahren zw. Tastatur und Prozess)*/ else { p=inportb(0x60); if(s<1) { y=p; /*Deblockade von k muß nicht implementiert werden, da in k ein *polling, eine dynamische Blockade, durch s=0 freigegeben*/ } } } Isabel Maine C. Drost Seite 6 von 16 ... do { asm{sti; nop; cli} }while (s<0); Seminar Echzeitverarbeitung Seminar 3.2 Algorithmen s=0 /*sema-Initioalisierung*/ interupt alttaste=getvect(9) Tastaturinterupt auf Prozess p umlenken PIC reaktivieren Prozessor - int sperren s++ s-s<0 j Prozess - B (Tastatur ISR) für immer(kein C-Code, realisisert durch wiederholtes Drücken einer Taste) Warten auf Tastendruck (ebenfalls bereits realisisert) Prozess_k blocken j Prozess_p blockieren n y=p j s>0 s>1 p=x Prozess k um ca. 1s verzögern s<1 n y=p Prozess p deblockiern Tastencode y anzeigen P=X (inportp() j n Prozessor-int freigeben n k deblockieren Prozessor_int freigeben (irret, ist implizit Bestandteil einer ISR in C) Abbildung 3-2; ISR zur Demonstration eines gepufferten Nachrichtenaustauschs solange y!=129 ISR zurücksetzen Abbildung 3-1; Beispiel Nachrichtenaustausch Hintergrundprogrammalgorithmus Praktikum zum Nachrichtenaustausch zwischen abhängigen parallelen Prozessen - ISR Praktikum zum Nachrichtenaustausch zwischen abhängigen parallelen Prozessen - Code für dynamisches Warten/ dynamische Blockade von Prozess k 4 Seminar Prozeß 0 (Hintergrundprozeß) 1) Aktivierung des EZBS-kerns 2) Starten von Prozeß 10 (Uhrprozeß) mit Priorität 10 und 1kByte Stack 3) Erwarten der Eingabe von Alarmnummer n (n=1 ... 9) und Alarmzeit (t=1 ... 655s) 4) Starten des Prozesses n, Priorität n und 2kByte Stack 5) Verzögerung von n um t Sekunden 6) Wiederholung von 3. bis 5., Abbruch bei Eingabe von t=0s Prozeß 10 (Uhrprozeß) 1) Eingabe der Uhrzeit mit hh:mm:ss Isabel Maine C. Drost Seite 8 von 16 2) 3) 4) 5) 6) zyklische Selbstverzögerung um 1s Erhöhen der Uhrzeit um 1s Uhrzeit in rechter oberer Bildschirmecke anzeigen Selbstanhalten des Prozesses Wiederholung von 3. bis 5. für immer Prozesse 1 ... 9 (Alarmprozesse) 1) Selbstanhalten des Prozesses n 2) Anzeige der Alarmnummer und Uhrzeit 3) Auslösen eines Pieptons (z.B. 1kHz für 1s) 4) Selbstterminierung des Prozesses #include <stdio.h> #include <mrt86.h> PROCESS Uhrzeit; PROCESS Alarm; void main(void) { unsigned char n; float t; ACTIVATE_MRT86(exit, 0); START_PROCESS(10, 10, 4, Uhrzeit); do { gotoxy(1, 2); clreol(); printf("Alarmnummer: (1...9)"); scanf("%u", &n); printf("Alarmzeit: (1...655) "); scanf("%u", &t); if(t==0.0) return; START_PROCESS(n, n, 8, Alarm); DELAY_ONCE(n, (unsigned)(t*100)); }while(1); } PROCESS Uhrzeit { unsigned char x, y, h, m, s; x=wherex(); y=wherey(); gotoxy(1, 1); printf("Uhrzeit in der Form hh:mm:ss: "); scanf("%u:%u:%u", &h, &m, &s); gotoxy(x, y); DELAY_CYCLIC(0, 100); while(1) { /*nicht dass mir ein Interrupt dazwischenhaut und ich s inkrementiere, m *oder h aber nicht mehr inkrementieren kann, weil inzw. ein anderer *Prozess dran ist */ DISABLE_INTERRUPT(); s=(s+1)%60; if(s==0) { m=(m+1)%60; if(m==0) h=(h+1)%24; } ENABLE_INTERUPT(); x=wherex(); y=wherey(); gotoxy(70, 1); printf("%2d:%02d:%02d", h, m, s); gotoxy(x, y); HOLD_PROCESS(0); } } PROCESS Alarm { Seminar Echzeitverarbeitung Semaphoren im MRT86 } unsigned char x, y; HOLD_PROCESS(0); x=wherex(); y=wherey(); gotoxy(1, PROCESS_NUMBER()+4); printf("Alarm %u um %u:%u:%u", PROCESS_NUMBER(), h, m, s); gotoxy(x, y); sound(1000); DELAY_ONCE(0, 100); nosound(); x=wherex(); y=wherey(); gotoxy(1, PROCESS_NUMBER()+4); clreol(); gotoxy(x, y); Beispiel eines Alarms mit dem MRT86 Berlinwoche 5 Semaphoren im MRT86 REQUEST_SEMAPHORE(SEMA) – Semaphore anfordern RELEASE_SEMAPHORE(SEMA) – Semaphore freigeben SEMA ist ein Zeiger auf eine int-Variable im globalen Speicher. Semaphor muß definiert vorbelegt sein (standardgemäß mit 0) 15 Wertebereich: 0 ... 255 0 87 Semaphorwert 0 oder Nr. des 1. durch das Semaphor blockierten Prozesses #include <mrt86.h> ... int bs_anz=1; char status[8][6]={"RUN", "RDY", "HOLD", "WAIT", "W&H", "BLOCK", "B&H", "INACT"}; PROCESS Anzeige; void main(void) { int i; ACTIVATE_MRT86(exit, 0); for(i=1; i<=5; i++) START_PROCESS(i, i, 0, Anzeige); getch(); } PROCESS Anzeige { int i, j; while(1) { REQUEST_SEMAPHORE(&bs_anz); DELAY_ONCE(rand(5)+1, 100); for(i=1; i<5; i++) { /* verschiebe ProcessState von i um 5 Bitstellen nach rechts. * 8 7 6 | 5 4 3 2 1 * STATUS | PRIORITÄT */ j=PROCESS_STATE(i)>>5; /*ist der Prozess i nicht der laufende Prozess*/ if(PROCESS_NUMBER()!=i) j++; if(j==8) i=7; printf("%7s", status[j]); } printf("\n"); RELEASE_SEMAPHORE(&bs_anz); } } Isabel Maine C. Drost Seite 10 von 16 Praktikum zu Semaphoren – speisende Philosophen Algorithmus: Philosoph Hauptprozess r=Prozeßnummer MRT86 aktivieren l=r%5+1 for i=1 bis 5 für immer Bildschirmposition(x[i], y[i]-1) Bildschirmposition(x[r], y[r]) Anzeige: Philosoph i Anzeige: "denkt" Prozeß i mit höchster Prio auf Philosoph starten Selbstanhalten des Prozesses Bildschirmposition(x[r], y[r]) Eingabe Prozeßnummer 1... 5 Anzeige: "will essen" Prozess mit Prozeßnummer fortsetzen Semaphor gabel[r] anfordern solange Prozeßnummer >0 Bildschirmposition (x[r], y[r]) Anzeige: "hat rechte" START_PROCESS(i, 0, 0, PHILOSOPH); Selbstverzögerung um 1 s Definition der Semaphoren: int gabel[6]={0, 1, 1, 1, 1, 1}; Semaphor gabel[l] anfordern unsigned char x[6]={0, 3, 4, 60, 18, 8}; y[6]={0, 2, 11, 22, 22, 11}; Anzeige: "esse" Selbstanhalten des Prozesses Semaphor gabel[r] und gabel[l] freigeben 6 Seminar – die Flußüberfahrt Bauer Bauer Boot Wolf LU LU LR LR FZ Ziege RU RU Kohl LU LR LR Ziege RU FK LU FK RU FZ Wolf Fluß RL RL RL Kohl LU ... linkes Ufer LR ... Überfahrt RU ... rechtes Ufer FZ ... frißt Ziege FK ... frißt Kohl RL Seminar Echzeitverarbeitung Seminar – die Flußüberfahrt Der schlafende Barbier Wartezimmer Barbierzimmer Weg des Barbiers Kunden dürfen bei leuchtender Lampe ins Barbierzimmer Am Wartezimmer ist eine Schiebetür, die entweder das Barbierzimmer, oder den Eingang freigibt. Bei zu langer Zeit ohne Kunden, schläft der Barbier ein, neue Kunden wecken ihn. Problemstellung zum schlafenden Barbier Kunden 1... 100 Barbier freie Stühle 100 unfrisiert 10 Sessel frei Gibt Sessel frei, schaltet Lampe ein ins Wartezimmer treten warten auf Kunden t=10min wartet t<10min einschlafen tritt ins Barbierzimmer schlafen Wartezimmertür offen wird bedient geweckt werden durch Kunden Kunde bereit verläßt Barbierzimmer Barbierzimmertür offen Kunden bedienen Kunde verabschieden Kunde ist fertig verläßt Wartezimmer Grobentwurf eines ersten Petrinetzen zum schlafenden Barbier Isabel Maine C. Drost Seite 12 von 16 Verfeinerung der Transition "tritt ins Wartezimmer" 100 läßt Haare wachsen fordert Stuhl an freie Stühle prüft Türstellung Barbierzimmer tür (offen) schiebt Tür Wartezimmertür geht durch Wartezi.tür gibt Tür frei wartet 7 Seminar – Problem von n-Lesern, und einem Schreiber u 1..n An Leser l l E l=i i=l l l k i i 1..n M M k E A s s M={1 .. n} M={1 .. n} s s 1..m m - Schreiber; M ⊆ {1 ... n} Seminar Echzeitverarbeitung Seminar – Das Problem der drei Raucher 8 Seminar – Das Problem der drei Raucher Serviererin wählt zufällig zwei Utensilien, von denen sich die Raucher anschließend nehmen können Serviererin Tabak Papier Feuer Raucher fertig wartet auf Fertigstellung nimmt Papier wartet auf Papier wartet auf Tabak wartet auf Tabak fertig nimmt Tabak raucht P T F nimmt Feuer wartet auf Feuer fertig nimmt Tabak wartet auf Feuer nimmt Feuer raucht raucht nimmt Papier wartet auf Papier fertig Verklemmungserkennung/ -behandlung in Petrinetzen: Verklemmungen treten beim Zugriff auf globale Betriebsmittel auf notwendige Bedinungen: • umstrittene Betriebsmittel sind lediglich exklusiv benutzbar • umstrittene BM können nicht entzogen werden • Prozesse belegen zugewiesene BM und warten auf weitere • eine zyklische Kette von Prozesses existiert, von denen jeder mindestens ein BM besitzt, das der nächste in der Kette benötigt. Isabel Maine C. Drost Seite 14 von 16 Beseitigung der Verklemmung: • Erkennen der Verklemmung zur Laufzeit und ihre gewaltsame Auflösung: canceln der beteiligten Prozesse (siehe Windows) - Man nimmt Verklemmungen in Kauf, da diese Variante billiger ist, als die Nutzung der beiden folgenden Lösungen. - man überprüft mit Hilfe einer Zeitüberwachung (watchdog), ob das angeforderte BM zugewiesen wurde, - nach Ablauf der Zeit startet man einen Algorithmus, der die Art der Verklemmung ermittelt und sie aufhebt • "Vorhersehen" der Anforderungen folgender Prozesse und evtl. Nichtgewähren eines BM, obwohl es frei ist. Analyse der zukünftigen BM-Anforderungen und Verbieten von Zuständen, die zu Verklemmungen führen könnten. Æ Laufzeitanalyse - ist in sehr wenigen Fällen möglich (sehr hoher Aufwand) Beispiel: Bankiersalgorithmus (Bankier hat eine gewisse Summe und Kunden, die Forderungen in maximaler Höhe der Summe des Bankiers hat. siehe Herrtwich/Hommel) • Verklemmung beim Entwurf des Systems vermeiden (eine der 4 obigen Bedinungen verhindern) - gleichzeitige Benutzung des BM durch mehrere Prozesse (z.B. Druckerwarteschlange) - sofortige Rückgabe des BM, falls es anderweitig angefordert wird - BM-Vergabe en-bloc (schlechte Auslastung der Ressourcen) - problemspez. Regeln (z.B. Linksabbieger im Straßenverkehr) Im Praktikum: 1) Petrinetz in obiger Form (ohne Verklemmungserkennungen/ -behandlungen) umsetzen 2) Verklemmungserkennung (Watchdog) 3) Verklemmungsbeseitigung (BM – Entzug und Neustart der Raucherprozesse) > MRT86 hat hier einen Bug; ist ein Prozeß im Zustand block, sollte er beendet werden. Hier muss er aber erstmal raus kommen aus diesem Zustand, Abhilfe: Gib den Prozessen ihre BM und beende sie danach 4) Verklemmungsverhütung durch BM-Zuweisung en-block Æatomare Aktionsfolge; Prüfen, ob BM verfügbar, ja: Anforderung beider BM; nein: Zeitverzögerung Seminar - Ereignisreaktion 9 PLAN_EVENT (EVT, ACT, RROC, PRM) für (externe) Interrupts vorplanen EVT – Ereignisnummer (Interuptvektor, EVT=0…255) EVT = 100hex+Ereignisnummer bedeutet den Aufruf der MRT86Aktion, dann Ausführung der ursprünglichen ISR ACT – Aktionsnummer (ACT=0 ... 6, ACT>6: Ereignis ignorieren Æ Befehl iret ausführen) PROC – Prozessnummer (PROC = 1...255, PROC=0: für lfd. Prozess planen) Eigene ISR 0H TastaturInt : 4H Tastatur ISR 8H 24H … Tastatur-ISR eigene ISR PRM – Aktionsparameter (von Aktion abhängig) Funktion: Die Aktion ACT wird vorgeplant für den Fall, dass Ereignis EVT (wiederholt) eintritt. Die Aktion wird später bei Eintritt des Ereignisses für Prozess PROC ausgeführt. Mögliche Aktionen: 0 – STOP (Prozess PROC stoppen, PRM: beliebig) 1 – CONTN (Process PROC fortführen, PRM: beliebig) 2 – HOLD (Process PROC anhalten, PRM: beliebig) 3 – ONCE (Process PROC einmalig verzögern, PRM: Verzögerungszeit) 4 – CYCL (Process PROC zyklisch verzögern, PRM: beliebig) 5 – PRIO (Process PROC new priorisieren, PRM: Priorität) 6 – RELE (Semaphore freigeben, PRM: Adressoffset des Sem.) >6 – CLEAR (Vorplanung löschen, Ereignis wird im weiteren ignoriert, urspüngl. ISR anspringen, PRM: beliebig) Seminar Echzeitverarbeitung Seminar - Ereignisreaktion für (externe) Interrupts vorplanen Beispiel: Meßwerterfassung ADU – löst Interrupt 11 (IRQ 3) nach vollendeter Wandlung aus. Annahme: fiktiver 12Bit – A/D – Wandler; Meßwert 0: 0V, Meßwert 4095: 5V Adresse 260H – LowByte (8Bit) Adresse 261H – HighByte (4Bit) Meßwerterfassung ADU - Treiber (ISR für A/D- Wandler) Eingabe: n (Meßwertanzahl 1... 100) Prozeßfortführung bei Ereignis 11 planen: MRT86 aktivieren PLAN_EVENT(0, 11, CNTN, 0); ADU - Treiber mit höchster Prio. Starten Interrupt 11 (IRQ 3) im PIC aktivieren: ADU - Simulator mit niedrigerer Prio starten outportb(0x21, inportb(0x21)&0xF7); Solange ADU - Treiber nicht gestoppt Für i=0 bis n-1 Selbstanhalten des Prozesses Anzeige der Meßwerte ADU - Simulator Zufallsgenerator einstellen Für i=0 bis n-1 PIC reaktivieren: outportb(0x20, 0x20); Meßwert eingeben: MW[i ]=inportb(0x260H) + 256*inportb(0x261H); Interrupt sperren(IRQ3 im PIC): Auf Tastendruck warten (getch) outportb(0x21, inportb(0x21) | 0x08); Interrupt 11 auslösen: asm int 11; PLAN_EVENT(0, 11, CLR, 0); MWE[i ]=zufallszahl Ereignisplanung löschen Meßwertnummer anzeigen Isabel Maine C. Drost Seite 16 von 16
© Copyright 2024 ExpyDoc