Keyboard Controller — Änderungen 6318 → 6319

Zeile 223: Zeile 223:
 
== Tastaturtreiber ==
 
== Tastaturtreiber ==
 
Im Folgenden soll genauer auf die Ansteuerung der Tastatur als ganzes
 
Im Folgenden soll genauer auf die Ansteuerung der Tastatur als ganzes
−
eingegangen werden, also das auslesen und verarbeiten der vom Benutzer
+
eingegangen werden, also das Auslesen und Verarbeiten der vom Benutzer
−
gedrückten Tasten. Dabei wird nur auf die manuelle Ansteuerung ohne
+
gedrückten Tasten. Dabei wird nur die manuelle Ansteuerung ohne
 
BIOS-Funktionen behandelt, wie sie benötigt wird, wenn die Tastatur im
 
BIOS-Funktionen behandelt, wie sie benötigt wird, wenn die Tastatur im
 
Protected Mode angesteuert werden soll. Es wird davon ausgegangen, dass die
 
Protected Mode angesteuert werden soll. Es wird davon ausgegangen, dass die
Zeile 231: Zeile 231:
  
 
=== Initialisierung ===
 
=== Initialisierung ===
−
Bevor man die Tastatur benutzt, ist es ratsam sie erstmal in einen bekannten,
+
Bevor man die Tastatur benutzt, ist es ratsam, sie erst einmal in einen bekannten,
 
sauberen Zustand zu bringen. Im  
 
sauberen Zustand zu bringen. Im  
 
[http://git.tyndur.org/?p=tyndur.git;a=blob;f=src/modules/kbc/keyboard.c Tastaturtreiber von tyndur]
 
[http://git.tyndur.org/?p=tyndur.git;a=blob;f=src/modules/kbc/keyboard.c Tastaturtreiber von tyndur]
 
hat sich nach einigem herumexperimentieren mit verschiedenen Emulatoren die
 
hat sich nach einigem herumexperimentieren mit verschiedenen Emulatoren die
 
folgende einfache Initialisierung bewährt:
 
folgende einfache Initialisierung bewährt:
−
* Solange das Bit 0 im Statusregister (Puffer voll) gesetzt ist Bytes aus dem Datenregister lesen. Das hilft wenn schon vor der initialisierung des Treibers irgendwelche Tasten betätigt wurde, da der KBC dann keine weiteren Zeichen sendet, bis der Puffer geleert (ausgelesen wurde), das tritt zum Beispiel im Zusammenhang mit GRUB oft auf, wenn der Benutzer die Taste zu lange gedrückt hält.
+
* Solange das Bit 0 im Statusregister (Puffer voll) gesetzt ist Bytes aus dem Datenregister lesen. Das hilft, wenn schon vor der initialisierung des Treibers irgendwelche Tasten betätigt wurde, da der KBC dann keine weiteren Zeichen sendet, bis der Puffer geleert (ausgelesen wurde). Das tritt zum Beispiel im Zusammenhang mit GRUB oft auf, wenn der Benutzer die Taste zu lange gedrückt hält.
−
* Tastatur mit Befehl 0xF4 aktivieren Andere Kombinationen wurden auch getestet, haben aber Probleme bereitet, unter anderem war Zeitweise ein Reset der Tastatur drin, was dazu geführt hat, dass diese unter gewissen Emulatoren überhaupt nicht mehr funktionierte.
+
* Tastatur mit Befehl 0xF4 aktivieren andere Kombinationen wurden auch getestet, haben aber Probleme bereitet, unter anderem war Zeitweise ein Reset der Tastatur drin, was dazu geführt hat, dass diese unter gewissen Emulatoren überhaupt nicht mehr funktionierte.
  
−
Dieser Code könnte beispielsweise folgendermassen aussehen:
+
Dieser Code könnte beispielsweise folgendermaßen aussehen:
 
<c>
 
<c>
 
static void send_command(uint8_t command);
 
static void send_command(uint8_t command);
Zeile 269: Zeile 269:
 
gedrückt wird, und nicht darauf warten muss. Dabei ist es wichtig, dass die
 
gedrückt wird, und nicht darauf warten muss. Dabei ist es wichtig, dass die
 
Routine zur Behandlung der Tastatur-IRQs vor der oben angegebenen
 
Routine zur Behandlung der Tastatur-IRQs vor der oben angegebenen
−
Initialisierung erfolgt, da sich sonst möglicherweise üble Race-Conditions
+
Initialisierung erfolgt, da sich sonst möglicherweise üble [[Race_Condition|Race-Conditions]]
−
ergeben, also konkret wenn der Puffer bereits geleert wurde, und noch vor dem
+
ergeben, also konkret wenn der Puffer bereits geleert wurde und noch vor dem
 
Registrieren der IRQ-Routine eine Taste gedrückt wird, dann ist der Puffer
 
Registrieren der IRQ-Routine eine Taste gedrückt wird, dann ist der Puffer
 
der Tastatur voll, und sie schickt somit auch keine IRQs mehr, bis er geleert
 
der Tastatur voll, und sie schickt somit auch keine IRQs mehr, bis er geleert
Zeile 276: Zeile 276:
  
 
=== IRQ-Handler ===
 
=== IRQ-Handler ===
−
Nun sind wir also bereit Tastendrücke von der Tastatur einzulesen. Im
+
Nun sind wir also bereit Tastendrücke von der Tastatur einzulesen. Im Folgenden wird genauer darauf eingegangen, wie wir die Tastendrücke, die wir
−
folgenden wird genauer darauf eingegangen, wie wir die Tastendrücke die wir
 
 
vom Kontroller über einen IRQ signalisiert erhalten, verarbeiten können.
 
vom Kontroller über einen IRQ signalisiert erhalten, verarbeiten können.
 +
 
Der erste und wichtigste Schritt in unserer IRQ-Behandlungsroutine ist es,
 
Der erste und wichtigste Schritt in unserer IRQ-Behandlungsroutine ist es,
 
das vom Tastaturkontroller bereitgestellte Byte aus dem Puffer zu lesen. In
 
das vom Tastaturkontroller bereitgestellte Byte aus dem Puffer zu lesen. In
−
einem weiteren Schritt müssen wir jetzt entscheiden womit wir es bei diesem
+
einem weiteren Schritt müssen wir jetzt entscheiden, womit wir es bei diesem
 
Byte nun genau zu tun haben. Eine erste Unterscheidung, die wir machen müssen,
 
Byte nun genau zu tun haben. Eine erste Unterscheidung, die wir machen müssen,
 
ist die Unterteilung in gedrückte und gelöste Tasten, was uns durch das oberste
 
ist die Unterteilung in gedrückte und gelöste Tasten, was uns durch das oberste
Zeile 287: Zeile 287:
  
 
Der Rest des Bytes ist ein Scancode,
 
Der Rest des Bytes ist ein Scancode,
−
der uns angibt um welche Taste es sich handelt. Dieser Scancode hat überhaupt
+
der uns angib,t um welche Taste es sich handelt. Dieser Scancode hat überhaupt
−
nichts mit irgendwelchen Zeichen zu tun, er gibt uns nur an welche Taste
+
nichts mit irgendwelchen Zeichen zu tun, er gibt uns nur, an welche Taste
 
gedrückt oder gelöst wurde, und muss von uns manuell mit einer Scancode-Tabelle
 
gedrückt oder gelöst wurde, und muss von uns manuell mit einer Scancode-Tabelle
 
in die korrespondierenden Zeichen umgewandelt werden. Dabei muss man sich
 
in die korrespondierenden Zeichen umgewandelt werden. Dabei muss man sich
 
bewusst sein, dass für die Tastatur eine Steuertaste, wie zum Beispiel die
 
bewusst sein, dass für die Tastatur eine Steuertaste, wie zum Beispiel die
−
Umschalttaste oder Caps lock, genau das selbe ist wie beispielsweise ein "a".
+
Umschalttaste oder Capslock, genau das Selbe ist wie beispielsweise ein "a".
−
Wird beispielsweise Umschalt+a gedrückt, um ein grosses "a" zu erhalten, schickt
+
Wird beispielsweise Umschalt+a gedrückt, um ein großes "a" zu erhalten, schickt
 
uns der Tastaturkontroller 2 Bytes, eines Umschalttaste gedrückt und ein anderes
 
uns der Tastaturkontroller 2 Bytes, eines Umschalttaste gedrückt und ein anderes
 
"a" gedrückt. Es ist also Aufgabe des Treibers diese Tasten entsprechend zu
 
"a" gedrückt. Es ist also Aufgabe des Treibers diese Tasten entsprechend zu
 
interpretieren.
 
interpretieren.
  
−
Um das ganze noch komplizierter zu machen, gibt es noch so genannte Extented
+
Um das Ganze noch komplizierter zu machen, gibt es noch so genannte ''Extented
−
Scancodes, davon gibt es zwei verschiedene Sorten. Diese werden mit E0- und E1
+
Scancodes'', davon gibt es zwei verschiedene Sorten. Diese werden mit E0- und E1
 
bezeichnet, und bestehen aus 2 (E0) und 3 (E1) Bytes. Das erste Byte eines
 
bezeichnet, und bestehen aus 2 (E0) und 3 (E1) Bytes. Das erste Byte eines
−
E0-Scancodes hat überraschenderweise den Wert 0xE0, während das zweite Byte um
+
E0-Scancodes hat überraschenderweise den Wert 0xE0, während das zweite Byte beinhalte, um
 
welchen e0-Scancode es sich genau handelt. E1-Scancodes bestehen aus 3 Bytes,
 
welchen e0-Scancode es sich genau handelt. E1-Scancodes bestehen aus 3 Bytes,
−
das erste hat den Wert 0xE1 während die folgenden zwei Bytes zu einem
+
das Erste hat den Wert 0xE1 während die folgenden zwei Bytes zu einem
 
Scancode-Wert kombiniert werden. Dabei muss beachtet werden, dass bei den
 
Scancode-Wert kombiniert werden. Dabei muss beachtet werden, dass bei den
 
Extended-Scancodes das Bit 8 des 2. und 3. Bytes darüber Aufschluss gibt, ob es
 
Extended-Scancodes das Bit 8 des 2. und 3. Bytes darüber Aufschluss gibt, ob es
Zeile 309: Zeile 309:
 
E0-Scancodes werden mit unterschiedlichen IRQs gesendet, man muss sich den
 
E0-Scancodes werden mit unterschiedlichen IRQs gesendet, man muss sich den
 
aktuellen Zustand im Code also irgendwie merken. Bei Extended Scancodes
 
aktuellen Zustand im Code also irgendwie merken. Bei Extended Scancodes
−
gibt es noch eine weitere Stolperfalle und zwar sind das die so genannten "fake
+
gibt es noch eine weitere Stolperfalle und zwar sind das die so genannten ''"fake
−
shifts" [http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.6 vgl.]
+
shifts"'' [http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.6 vgl.]
  
−
So nun wissen wir also mit welchem Scancode wir es zu tun haben, als nächstes
+
So, nun wissen wir also, mit welchem Scancode wir es zu tun haben. Als nächstes
 
müssen wir den seltsamen Scancode jetzt in etwas sinnvolles umwandeln. Hier gibt
 
müssen wir den seltsamen Scancode jetzt in etwas sinnvolles umwandeln. Hier gibt
 
es jetzt zwei Möglichkeiten, entweder wir wandeln sie direkt in ASCII-Zeichen
 
es jetzt zwei Möglichkeiten, entweder wir wandeln sie direkt in ASCII-Zeichen
−
(oder welche Kodierung auch immer) um, oder wir wandeln sie in ein internes
+
(oder welche Kodierung auch immer) um oder wir wandeln sie in ein internes
 
Format um (meist Keycodes genannt), welches wir dann weitergeben.
 
Format um (meist Keycodes genannt), welches wir dann weitergeben.
  
Zeile 395: Zeile 395:
 
einzig mögliche, hier muss man sich selbst überlegen wie das für den konkreten
 
einzig mögliche, hier muss man sich selbst überlegen wie das für den konkreten
 
Anwendungsfall am komfortabelsten ist.
 
Anwendungsfall am komfortabelsten ist.
−
 
  
 
== Beispiele zur Benutzung der KBC Funktionen ==
 
== Beispiele zur Benutzung der KBC Funktionen ==