Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: mineorbit am 04. July 2013, 21:22

Titel: kbc hilfe
Beitrag von: mineorbit am 04. July 2013, 21:22
Hallo lowlevel community!
Hoffentlich störe ich euch nicht mit dem Thema,allerdings habe ich 3 Fragen zur kbc:
1:Zeichen ausgeben
Letztes mal habe ich euch gefragt wie man den Keycode die Zeichen umwandle, allerdings, kann es sein das irgendwas falsch mache.
Das ganze funktioniert doch so; scancode -> Keycode -> Zeichenkette ?
Wie trage ich die Zeichen richtig in den Array ein?
Das ist jetzt so bisher:
#include "console.h"
#include "keyboard.h"
#include "stdint.h"
char list[] = {
"01"
};
char getsym(int keycode)
{
if(keycode == 0x1c)
{
kexit();
}
  return list[keycode];
}
}
static uint8_t sc_to_kc[][128] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 00, 00, 86, 87, 88, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 },  { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 96, 97, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 00, 100, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 102, 103, 104, 00, 105, 00, 106, 00, 107, 108, 109, 110, 111, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }, }; 
uint8_t translate_scancode(int set, uint16_t scancode)
{
uint8_t keycode = 0;
switch (set) { 
case 0:
 keycode = sc_to_kc[0][scancode];
 break;
case 1:
  keycode = sc_to_kc[1][scancode];
 break;
   switch (scancode) {
  case 0x451D: keycode = 119; break; default: keycode = 0x0; }; break; }
if (keycode == 0) {
 } return keycode;
}
 
void init_keyboard(void);
static void keyboard_command(uint8_t command);
void keyboard_interrupt(void);
void init_keyboard(void)
{
 
    while (inb(0x64) & 0x1) {
        inb(0x60);
    }   
 
 
    keyboard_command(0xF4);
}
 
static void keyboard_command(uint8_t command)
{
   
    while ((inb(0x64) & 0x2))
{
}
    outb(0x60, command);
}
void keyboard_interrupt(void){
     char text;
    uint8_t scancode;
    int keycode;
    uint8_t break_code = 0;
 
    // Status-Variablen fuer das Behandeln von e0- und e1-Scancodes
    static int     e0_code = 0;
    // Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste
    // Datenbyte gelesen wurde
    static int      e1_code = 0;
    static uint16_t  e1_prev = 0;
 
    scancode = inb(0x60);
 
    if ((scancode & 0x80) &&
        (e1_code || (scancode != 0xE1)) &&
        (e0_code || (scancode != 0xE0)))
    {
        break_code = 1;
        scancode &= ~0x80;
    }
 
    if (e0_code) {
        if ((scancode == 0x2A) || (scancode == 0x36)) {
            e0_code = 0;
            return;
        }
 
        keycode = translate_scancode(1, scancode);
        e0_code = 0;
    } else if (e1_code == 2) {
     /*
        e1_prev |= ((uint16_t) scancode <<;
        keycode = translate_scancode(2, e1_prev);
        e1_code = 0;
*/
    } else if (e1_code == 1) {
       
        e1_prev = scancode;
        e1_code++;
    } else if (scancode == 0xE0) {
        // Anfang eines e0-Codes
        e0_code = 1;
    } else if (scancode == 0xE1) {
        // Anfang eines e1-Codes
        e1_code = 1;
    } else {
        // Normaler Scancode
        keycode = translate_scancode(0, scancode);
       
    }
      text = getsym(keycode);
        if(break_code == 0)
 {
 
        kprintf("%c",text);
  }
        else
 {
       
 }     
}
 

2:Speziell Zeichen abfragen
Im Code steht:
if(keycode == 0x1c)
{
kexit();
}
kexit habe ich als Funktion gemacht um den PC runter zu fahren
Damit möchte ich erreichen ,dass beim Tasten druck von Enter der Computer heruntergefahren wird, dies funktioniert aber nicht,wie würde ich das Problem lösen?
3:Lesechar
Ansonsten, hätte jemand von euch einen Denk anstoß um ein char namens kreadf() zu machen?Das wäre spitze  :grin:
Freundliche Grüße,
 Mineorbit!
EDIT:
3 ist gelöst,ich hatte nur einen syntaxfehler gemacht.
 
Titel: Re: kbc hilfe
Beitrag von: Jidder am 10. July 2013, 02:05
Hoffentlich störe ich euch nicht mit dem Thema,allerdings habe ich 3 Fragen zur kbc:
Niemals. Dafür ist das Forum da ;)

Deine translate_scancode-Funktion könnte etwas aufgeräumt werden. Das zweite switch wird nie ausgeführt. Und das ist auch besser so, weil es keycode überschreibt.

Im Prinzip sollte der Code funktionieren. Das Array list solltest du mit den Werten aus der ersten Spalte von hier befüllen (nicht kopieren, die Arrays sind nicht kompatibel):

http://git.tyndur.org/?p=tyndur.git;a=blob;f=src/modules/vterm/keymaps/de.c;h=53612b6a8cad464ae8e93625e624879520bc59f0;hb=HEAD

Dann hast du alle Tasten ohne Shift. Wenn du Shift unterstützen willst, musst du das Array ähnlich wie tyndur entweder zweidimensional machen oder zwei Arrays anlegen. Und dann musst du eine Status-Variable haben, die gesetzt und gelöscht wird wenn Shift gedrückt bzw. losgelassen wird.

Oder du experimentierst selbst rum: Wenn du keycode beim Tastendruck ausgeben lässt, kannst du dir selbst so eine Tabelle anlegen, die besagt, welcher keycode zu welcher Taste gehört. Ist natürlich etwas Fleißarbeit.

Oder du nimmst die Werte von hier (für englisches Layout) http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.4 Die fettgedruckte Zahl ist der keycode und du nimmst entweder das erste oder das zweite dahinterstehende Zeichen (für kein Shift bzw. Shift gedrückt). Die Zeichen schreibst du an die entsprechende Stelle des Arrays. Bei Tasten die keinem Zeichen entsprechen (ESC, Shift, Alt, Strg, Caps, Backspace, ...) kannst du natürlich nur 0 eintragen.

Zu der Sache mit dem Herunterfahren: Funktioniert das Herunterfahren allgemein nicht, oder das Herunterfahren auf Tastendruck? Im ersteren Fall, kann dir keiner ohne Code von kexit weiterhelfen, und im zweiten Fall würde ich sagen, dass du erstmal andere Probleme lösen solltest.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 10. July 2013, 17:24
Vielen Dank für die Hilfe :lol:
Denn Array füll ich jetzt erstmal aus,wie gesagt.
Die funktion herunterfahren also kexit läuft, nur weiß ich nicht wie ich einzelne Tasten abfrage ob sie gedrückt wurden.Das würde ich später auch noch gerne in ein treiber reinbringen. Wie würde ich so ein lese-char machen? Ich hab das mal so versucht,dass ich alles in einen array eintragen lasse und das dann ausgebe,aber meine kprintf funktion kann noch keine arrays zurück geben. ich wollte erstmal nur in der test.bin,die ich umfunklt habe in console.bin umfunktioniert habe, mache ich nur gerade ein kommandozeile draus!
Vielen Dank,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 10. July 2013, 21:48
Also ich interpretiere die Frage mal so, dass du wissen willst, wie die Tastendrücke vom Treiber in die Programme kommen.

Im Prinzip brauchst du einen Puffer, in den du an das eine Ende Zeichen reinschreiben kannst, und am anderen Ende Zeichen wieder auslesen kannst. Das Teil heißt Double-Ended Queue (Deque) (http://de.wikipedia.org/wiki/Deque). Also eine Queue (http://de.wikipedia.org/wiki/Warteschlange_%28Datenstruktur%29). Zum Beispiel das BIOS implementiert das allerdings als Ringpuffer (http://de.wikipedia.org/wiki/Ringpuffer#Ringpuffer), welche nur rund 30 Zeichen oder so aufnehmen kann. Das kann einfacher sein, muss es aber nicht.

Dein Treiber muss also im IRQ-Handler das Zeichen für die gedrückte Taste in den Puffer schreiben, und wenn dein Programm eine getchar()-Funktion (oder so) aufruft, dann liest die Funktion das älteste Zeichen aus dem Puffer aus, und entfernt es aus dem Puffer.

Wenn du ein Programm mit Eingabeaufforderung bauen willst, dann brauchst du eine Funktion, die in einer Schleife getchar() aufruft, das gelesene Zeichen ausgibt und in einen eigenen Puffer schreibt. Die Schleife terminiert, wenn getchar() Enter zurück gibt. Danach interpretierst du den Inhalt des Puffers je nach dem welche Funktion das Programm haben soll.
Titel: Re: kbc hilfe
Beitrag von: Svenska am 10. July 2013, 21:57
Hallo,

der Tastaturtreiber muss nicht wissen, welche Tasten gerade gedrückt sind, sondern nur, welche Tasten gerade gedrückt oder losgelassen werden. Ausgenommen davon sind die Modifikatortasten (also Shift, Strg und so), für diese kannst du im Tastaturtreiber den Zustand nochmal extra speichern, wenn du möchtest. Übrigens funktioniert nicht jede Taste als Modikatortaste. Welche Tasten gehen und welche nicht, hängt vom elektrischen Aufbau der Tastatur ab.

Gruß,
Svenska
Titel: Re: kbc hilfe
Beitrag von: kevin am 10. July 2013, 22:19
Im Prinzip brauchst du einen Puffer, in den du an das eine Ende Zeichen reinschreiben kannst, und am anderen Ende Zeichen wieder auslesen kannst. Das Teil heißt Double-Ended Queue (Deque) (http://de.wikipedia.org/wiki/Deque).
Ist eine Deque nicht das Ding, wo man auf beiden Seiten sowohl lesen als auch schreiben kann? Auf der einen Seite reinschreiben und auf der anderen auslesen ist bei mir eine normale Queue.
Titel: Re: kbc hilfe
Beitrag von: Jidder am 11. July 2013, 00:10
Hast Recht. Ich hab bei Queue an Stack gedacht...
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 11. July 2013, 09:30
Vielen Dank!
Als erstes nehm ich mal den Bios-buffer(das kann ich ja später noch ändern!).
Wie fülle ich ihn auf und wie lese ich ihn aus?
Vielen Dank,
Mineorbit
Edit:
Das mit der zweiten Switch funtkion und ersten verstehe ich noch nicht.
die Funktion getsym, die den array list nutzt, soll ich weglassen, abeer list soll ich auffüllen,wofür?
Dede eh jetzt so aus:
#include "console.h"
#include "keyboard.h"
#include "stdint.h"
static uint8_t sc_to_kc[][128] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 00, 00, 86, 87, 88, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 },  { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 96, 97, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 00, 100, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 102, 103, 104, 00, 105, 00, 106, 00, 107, 108, 109, 110, 111, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 }, };
uint8_t translate_scancode(int set, uint16_t scancode)
{
uint8_t keycode = 0;
switch (set) { 
case 0:
 keycode = sc_to_kc[0][scancode];
 break;
case 1:
  keycode = sc_to_kc[1][scancode];
 break;
   switch (scancode) {
  case 0x451D: keycode = 119; break; default: keycode = 0x0; }; break; }
if (keycode == 0) {
 } return keycode;
}
 
void init_keyboard(void);
static void keyboard_command(uint8_t command);
void keyboard_interrupt(void);
void init_keyboard(void)
{
 
    while (inb(0x64) & 0x1) {
        inb(0x60);
    }   
 
 
    keyboard_command(0xF4);
}
 
static void keyboard_command(uint8_t command)
{
   
    while ((inb(0x64) & 0x2))
{
}
    outb(0x60, command);
}
void keyboard_interrupt(void){
     
    uint8_t scancode;
    int keycode;
    uint8_t break_code = 0;
 
    // Status-Variablen fuer das Behandeln von e0- und e1-Scancodes
    static int     e0_code = 0;
    // Wird auf 1 gesetzt, sobald e1 gelesen wurde, und auf 2, sobald das erste
    // Datenbyte gelesen wurde
    static int      e1_code = 0;
    static uint16_t  e1_prev = 0;
 
    scancode = inb(0x60);
 
    if ((scancode & 0x80) &&
        (e1_code || (scancode != 0xE1)) &&
        (e0_code || (scancode != 0xE0)))
    {
        break_code = 1;
        scancode &= ~0x80;
    }
 
    if (e0_code) {
        if ((scancode == 0x2A) || (scancode == 0x36)) {
            e0_code = 0;
            return;
        }
 
        keycode = translate_scancode(1, scancode);
        e0_code = 0;
    } else if (e1_code == 2) {
     /*
        e1_prev |= ((uint16_t) scancode <<;
        keycode = translate_scancode(2, e1_prev);
        e1_code = 0;
*/
    } else if (e1_code == 1) {
       
        e1_prev = scancode;
        e1_code++;
    } else if (scancode == 0xE0) {
        // Anfang eines e0-Codes
        e0_code = 1;
    } else if (scancode == 0xE1) {
        // Anfang eines e1-Codes
        e1_code = 1;
    } else {
        // Normaler Scancode
        keycode = translate_scancode(0, scancode);
       
    }
     
        if(break_code == 0)
 {
 
        kprintf("%c",keycode);
  }
        else
 {
       
 }     
}
 
 
Vielen Dank,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 12. July 2013, 00:28
Das mit der zweiten Switch funtkion und ersten verstehe ich noch nicht.
Vielleicht fällt dir das Problem auf, wenn der Code mal ordentlich formatiert ist. Ich hab einfach mal Leerzeichen und Zeilenumbrüche eingefügt:
uint8_t translate_scancode(int set, uint16_t scancode)
{
  uint8_t keycode = 0;

  switch (set) { 
    case 0:
      keycode = sc_to_kc[0][scancode];
      break;
    case 1:
      keycode = sc_to_kc[1][scancode];
      break;
      switch (scancode) {
        case 0x451D:
          keycode = 119;
          break;
        default:
          keycode = 0x0;
      };
      break;
    }

    if (keycode == 0) {

    }

    return keycode;
}

Ich weiß ja auch nicht, was der Code tun soll.

Als erstes nehm ich mal den Bios-buffer(das kann ich ja später noch ändern!).
Wie fülle ich ihn auf und wie lese ich ihn aus?

Ich kann dir hier keinen Ringpuffer erklären. Ich hab aber mal auf die Schnelle ein einfaches Programm gebastelt, das eine ähnliche Funktion erfüllt, und dich vielleicht inspiriert: http://codepad.org/4X9gbxCc Das hat eine add-Funktion, die Einträge in den Puffer schreibt, und eine read-Funktion, die wieder Einträge ausliest. Du kannst dir ja mal die Ausgabe ganz unten angucken, und das vergleichen mit dem, was die main-Funktion macht. Wenn du willst, kannst du dir auch so ähnliche Funktionen schreiben, ansonsten musst du dir mal ein Tutorial zu Ringpuffern zu Gemüte führen.

Titel: Re: kbc hilfe
Beitrag von: mineorbit am 12. July 2013, 17:41
Vielen Dank für den Code Jidder :grin:
Das konnte ich in zwischen einbinden.Also eigentlich soll translate scancode den scancode in keycode umwandlen. Meine Frage war nurnoch, muss ich den keycode auch noch weiter verarbeiten,oder ist er das zeichen oder der modifikator den ich ausgeben b.z.w prüfen will?

Vielen Dank,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: micha am 12. July 2013, 18:04
Meine Frage war nur noch, muss ich den Keycode auch noch weiter verarbeiten,oder ist er das zeichen oder der modifikator den ich ausgeben b.z.w prüfen will?

Ja, wenn du die Scancodes nicht direkt in ASCII umwandelst, sondern erst in Keycodes. (was sinnvoller ist).
Der Scancode ist bloß eine Nummer, die die Tastatur sendet. Diesen wandelst du dann um in einen Keycode, welcher dazu dient, eine Taste (z.b.: 'A', 'B', F1) zu identifizieren. Diese keycodes kannst du dann (falls es überhaupt ein buchstabe ist) in ASCII-Zeichen umwandeln und ausgeben.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 12. July 2013, 21:24
Vielen Dank!
Also bräüchte ich dann doch eine zweite Switch?Wie müsste die gemacht sein?
Vielen Dank für die Lösung der 2 anderen Fragen,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: micha am 12. July 2013, 22:01
einen Switch bräuchtest du nicht. einfach ein Array, bei dem der Index der Einträge dem Keycode entspricht und das ASCII -zeichen als Wert drin steht.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 13. July 2013, 17:35
Aha!
Wie wird dann der keycode zum Zeichen gemacht werden? Könntet ihr mir einen Beispielcode zeigen?Also brauch ich beide Switches(besser gesagt, ist das was man beim Interrupt erhält schon der scancode)? Was muss ich von dem momentanen Quellcode ändern damit es funktioniert.(Wenn ihr das machen würdet wäre das super!)
Viele Grüße,
Mineorbit
Edit:
Habe bereits auf google geguckt und in eurem forum, aber wie mache ich einen interrupt handler für irq's?.
Das einzigste was ich bisher finden konnte war, die funktion register_interrupt_handler().
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 28. July 2013, 16:36
Wie sieht denn dein Interrupthandler zur Zeit aus? Wenn du z.B. unser Tutorial (http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts) befolgt hast, reicht es erstmal aus, wenn du das letzte Code-Beispiel wie folgt anpasst:

if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {

    // Diese if-Abfrage ist neu.
    if (cpu->intr == 0x21) {
        keyboard_interrupt();
    }

    if (cpu->intr >= 0x28) {
        outb(0xa0, 0x20);
    }
    outb(0x20, 0x20);
}

Titel: Re: kbc hilfe
Beitrag von: mineorbit am 28. July 2013, 20:58
Aha danke,
Habt ihr zufällig eine liste mit den interrupt nummern für alle irqs?
Ansonsten, wie muss ich den Array für die umwandlung von keycode in ascii zeichen, und wie mache ich die umwandlungsfunktion :???:
(Ich bekomme das einfach nicht hin )
Den buffer habe ich schon vielen Dank für eure Hilfe!
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 28. July 2013, 21:17
Liste der IRQs (http://www.lowlevel.eu/wiki/IRQ#IRQ_Tabelle)

Ansonsten, wie muss ich den Array für die umwandlung von keycode in ascii zeichen, und wie mache ich die umwandlungsfunktion

Ich habe mal angefangen für die diese Tabelle (http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.4) in ein Array zu übertragen. Das Prinzip ist eigentlich ganz einfach.

Die fett gedruckten Zahlen auf der Seite sind der Scancode. Daneben steht entweder die Taste (ESC, Enter...) oder die beiden Zeichen die man bekommt wenn man die zum Scancode gehörige Taste drückt und dabei entweder Shift nicht gedrückt hält oder Shift gedrückt hält.

Beispielsweise steht da 02 (1!). Das heißt Scancode 2 ist die Taste 1! und dein Code muss jenachdem ob Shift gedrückt ist, entweder 1 oder ! als Zeichen zurück geben.

Ich habe dazu diese beiden Arrays angefangen zu befüllen. Im ersten Array stehen die Zeichen ohne Shift. Wie du siehst, habe ich für Tasten wie ESC, Ctrl, etc. einfach nur 0 eingetragen.

char keymap[] = {
0, /* nicht belegt */
0, /* ESC */
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',
'\b', /* backspace */
'\t', /* tab */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', ['', ']'
'\n', /* enter */
0, /* lctrl */
'a', 's', 'd', ....
};

char keymap_shift[] = {
0, /* nicht belegt */
0, /* ESC */
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
'\b', /* backspace */
'\t', /* tab */
'Q', 'W', 'E', 'R', 'T', 'Y', ...
};

char keycode_to_char(int keycode)
{
   /* wenn shift gedrückt wurde eine andere keymap nehmen */
   if (!shift) {
       return keymap[keycode];
   } else {
       return keymap_shift[keycode];
   }
}

Damit das funktioniert, musst du in keyboard_handler schauen ob Shift gedrückt oder losgelassen wurde, und dafür eine globale Variable, die ich mal shift genannt habe, auf true oder false setzen. Du musst also den Inhalt der verlinkten Seite weiter in das Array einfüllen, und dann solltest du die Funktion keycode_to_char benutzen können.

Edit: Die Funktion sollte keycode_to_char heißen nicht scancode_to_keycode. (Oder meintewegen scancode_to_char, wenn du auf keycodes verzichtest.) Siehe auch Svenskas Erläuterung.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 28. July 2013, 22:17
Vielen ,vielen Dank Jidder!
Jetzt hab ichs endlich verstanden, also ist es so, dass man als erstes den scancode bekommt und dann der keycode das zeichen ist was man haben will z.b A,B,C usw.
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Svenska am 29. July 2013, 00:09
Normalerweise läuft das so:

Der Scancode ist eine Bytefolge, die von der Tastatur abhängt (z.B. die Lauter- oder Leiser-Tasten an Notebooks sind von Hersteller zu Hersteller unterschiedlich). Um also die Eigenheiten der Tastatur zu aus den Programmen rauszunehmen, wandelt der Tastaturtreiber diesen Scancode in einen Keycode um.

Der Keycode ist eine Zahl, die für jede Taste eindeutig und dem Kernel bekannt ist. Nicht jede Tastatur kann jeden Keycode erzeugen (verschiedene Tastaturen haben verschiedene Tasten, z.B. hat deine Tastatur keine F13-Taste), aber verschiedene Tastaturen erzeugen mit den gleichen Tasten immer den gleichen Keycode.

Wenn ein Programm also die Keycodes direkt bekommen kann ("RAW-Modus"), dann kann es auf jede Taste reagieren, die es kennt. Braucht man für Spiele (z.B. Pfeiltasten, ...), deswegen wird das immer angeboten.

Den meisten Programmen sind die Tasten ziemlich egal, die möchten nur die Bedeutung haben ("COOKED-Modus"). Das Tastaturlayout gibt den einzelnen Keycodes eine Bedeutung. Gleiche Tasten können verschiedene Dinge bedeuten: Mit der Taste A auf meiner Tastatur kann ich die ASCII-Zeichen a, A, á, Á, æ oder Æ erzeugen, je nach Zustand von Shift, Alt und AltGr.

Also: Im Tastaturtreiber wird der Scancode in einen Keycode gewandelt, im Eingabesystem wird der Keycode dann entweder an die Anwendung durchgereicht oder erst in Zeichen gewandelt (vorverarbeitet) und dann weitergereicht - je nachdem, was die Anwendung wünscht. Die Vorverarbeitung kann auch erst innerhalb der Anwendung (z.B. Bibliothek) geschehen. Dann kannst du pro Anwendung verschiedene Tastaturlayouts haben.

Gruß,
Svenska
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 29. July 2013, 10:09
Danke für die Erklärung Svenska,
Habe schon eine idee wie ich das dann später als char in meine system lib einbauen kann.
Vielen Dank bisher,
Mineorbit
(Kann der thread bitte noch einwenig aufbleiben für den fall das nochimmer was nicht stimmt?)

Titel: Re: kbc hilfe
Beitrag von: Svenska am 29. July 2013, 18:31
(Kann der thread bitte noch einwenig aufbleiben für den fall das nochimmer was nicht stimmt?)
Threads werden hier üblicherweise nicht geschlossen.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 10. August 2013, 00:01
Hallo,
So jetzt ist alles umgesetzt, soweit klappt alles regel gemäß, nur hätte ich eine frage, ist ein keycode wirklich so lang?:
4294987295
Außerdem, welche Interrupt nummer brauche ich für die maus?
Viele Grüße,
Mineorbit
 
Titel: Re: kbc hilfe
Beitrag von: Jidder am 10. August 2013, 00:48
Also Keycodes sind ja eigentlich etwas, das du selbst definierst. Du hast das mit dem Array sc_to_kc in deinem vorangegangenen Post gemacht. Die Tastatur sendet Scancodes. 4294987295 ist kein gültiger Scancode, da Scancodes Bytes/Bytefolgen (also Werte zwischen 0 und 255) sind, aber da dein sc_to_kc-Array vom Typ uint8_t ist, ist das auch kein Keycode.

Normalerweise hätte ich gesagt, dass du ein Problem hast, dass irgendwie dieselben Symptome hat wie wenn ein (signed) char in signed int umgewandelt wird und anschließend als unsigned int ausgegeben wird. Aber da 4294987295 größer als 2^32 ist, würde ich sagen, dass du entweder die falsche Zahl genannt hast, dein Code sehr komische Sachen macht, oder die Ausgabe nicht korrekt funktioniert.


Außerdem, welche Interrupt nummer brauche ich für die maus?
IRQ 12
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 10. August 2013, 17:47
Vielen Dank,
das Problem hab ich schon fast gelöst, mir wird nur von anfang an irgend etwas in den buffer geschrieben.
Wie kann ich den buffer leeren?
Achja und wie kann ich Daten vom ersten ring in den 3 übergeben?
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 10. August 2013, 18:04
Wie kann ich den buffer leeren?
Den Puffer im Keyboard-Controller? Durch Auslesen und alles gelesene, was du nicht kennst, ignorieren.

Achja und wie kann ich Daten vom ersten ring in den 3 übergeben?
Systemaufrufe (http://www.lowlevel.eu/wiki/Teil_8_-_Ein_erstes_Programm#Syscalls).
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 10. August 2013, 22:01
 Vielen Dank aber wie mach ich das genau?
System aufrufe würde ich gerne nutzen, aber das funktioniert doch nur vom Programm im ring3 zum kernel in ring 1?
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 10. August 2013, 22:25
Klar das Programm löst Systemaufrufe aus, aber die können trotzdem Informationen an das Programm zurückgeben. Eine Möglichkeit wäre ein Systemaufruf, bei dem das Programm den Kernel fragt, ob eine Taste gedrückt wurde. Der Systemaufruf kann dann an das Programm entweder zurückgeben, dass keine Taste gedrückt wurde, oder aber den char bzw. Keycode der gedrückten Taste.

Wenn du das verlinkte Tutorial befolgst, kannst du dazu die Werte im struct cpu_state auswerten, und auch Rückgabewerte reinschreiben. Im Programm kannst du dann Inline Assembler (http://www.lowlevel.eu/wiki/Inline-Assembler_mit_GCC) verwenden, um das Ergebnis wieder auszulesen.

Übrigens ist der Kernel in Ring 0.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 11. August 2013, 11:26
Ok, also benutze ich den inline assembler und lege dann z.B auf eax den keycode?
Wie lese ich das dann beim programm wieder aus?
Viele Grüße, Mineorbit
Titel: Re: kbc hilfe
Beitrag von: streetrunner am 11. August 2013, 12:47
Zitat
Ok, also benutze ich den inline assembler und lege dann z.B auf eax den keycode?
Nicht ganz. Ich denke mal Dein Syscall ist ein einfacher Interrupt. Dein Interrupt-Handler sichert bei einem Interrupt alle Register auf den Stack. Die dabei entstandene Struktur kannst Du dann später auslesen und verändern. Beim zurückkehren werden alle Register vom Stack wiederhergestellt. Wenn Du nun die Struktur so änderst, dass Du in eax den Rückgabewert hast, wird dieser eben auch wieder hergestellt. Wenn Dein Programm dann nach dem Interrupt weiterläuft kannst Du mit Inline Assembler das Register eax in eine Variable Deiner Wahl befördern und damit ganz normal weiterarbeiten.
Gruß,
Streetrunner
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 11. August 2013, 15:18
Vielen Dank, wie wie löse ich es statdessen?
Über antworten freue ich mich sehr,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: MNemo am 11. August 2013, 15:44
streetrunner hat dir schon geschrieben wie es geht.

Abgesehen von der Möglichkeit Daten über die Register zu übergeben, hast du auf einem x86 aber auch keine "No-Write-Down"-Police. Es hindert dich also auch niemand daran, vom Kernel aus direkt in den Userspace zu schreiben, wenn du das willst.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 11. August 2013, 16:00
Also soll ich eax nur überschreiben und dann beim Programm irgendwie in eine variable packen?
Wenn ihr es mir erklären könntet wäre das sehr freundlich
Viele Grüße,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 11. August 2013, 16:31
streetrunner hat versucht dir folgendes zu erklären:

Wenn dein Code so aussieht wie hier (http://www.lowlevel.eu/wiki/Teil_8_-_Ein_erstes_Programm#Syscalls), kannst du eine Funktion zum Lesen von der Tastatur einfügen. Ich hab der Funktion mal die Nummer 879 gegeben.

struct cpu_state* syscall(struct cpu_state* cpu)
{
    switch (cpu->eax) {
        case 0: /* putc */
            kprintf("%c", cpu->ebx);
            break;

        case 879: /* NEU */
            cpu->eax =  ein wert aus dem puffer oder ein wert der anzeigt, dass der puffer leer ist;
            break;

    }
 
    return cpu;
}

Wenn ein Programm diesen Syscall aufrufen will, muss es sowas in der Art wie folgendes tun:
int key;
asm("int $0x30" : "=a" (key) : "a" (879));
// nun ist in key entweder die taste oder ein wert der anzeigt, dass keine taste gedrückt wurde.
Titel: Re: kbc hilfe
Beitrag von: mineorbit am 11. August 2013, 22:19
Ah, vielen Dank Jidder,
Nur benutze ich schon statt 879 lieber 2, 1 ist schon für mein clear funktion belegt.
Also brauche ich nur ein = für die rückgabe.
Danke Sehr,
Mineorbit
Titel: Re: kbc hilfe
Beitrag von: Jidder am 11. August 2013, 22:25
Also brauche ich nur ein = für die rückgabe.

Das ist nicht alles. Lies dir mal den Artikel zu Inline-Assembler (http://www.lowlevel.eu/wiki/Inline-Assembler_mit_GCC) durch und informier dich darüber wie Parameter übergeben werden. Du kannst natürlich dich auch bei Google oder Wikibooks über Inline Assembler informieren. Wenn du da was falsch machst, wird dir der Compiler keinen Hinweis geben was los ist, deswegen solltest du das schon verstehen.