Autor Thema: kbc scancode translate  (Gelesen 4187 mal)

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« am: 30. May 2013, 21:35 »
Hallo Low Level Community,
Wie im Betreff steht, würde ich gerne den scancode ,den ich erhalte ,translaten.
Dazu habe ich in eurem zu gehörigen Tutorial gleich hilfe gefunden,die aber irgendwie nicht funktioniert,
GCC sagt mir:
keyboard.c: In function ‘keyboard_interrupt’:
keyboard.c:31:9: warning: implicit declaration of function ‘translate_scancode’ [-Wimplicit-function-declaration]
keyboard.c: At top level:
keyboard.c:34:9: error: conflicting types for ‘translate_scancode’
keyboard.c:31:24: note: previous implicit declaration of ‘translate_scancode’ was here

Mein Code:
//Keyboard.c
#include "console.h"
#include "keyboard.h"
#include "stdint.h"

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){
 int scancode = inb(0x60);
        char keycode = translate_scancode(1,scancode);
 kprintf("%c",keycode);
}
 
 
Falls euch das hilft ohne die Funktion translate, gibt er mir bei z.B als scancode aus:1c 9c
Mein Frage wäre:
-muss ich uint8 translate_scancode speziell programmieren, oder ist das eine fertige Funktion aus dem Compiler oder einer Header file?
-Hab ich irgendwas mit den scancodes falschgemacht?
 

 
Ich freue mich auf Antworten!
Mineorbit

 

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 30. May 2013, 21:53 »
translate_scancode in dem KBC Beispiel ist eine C Funktion wie jede andere.
Natürlich musst du die selber deklarieren und definieren.

Und im Artikel steht ausdrücklich:
Zitat
Dieses Codestück unternimmt genau die oben beschriebenen Schritte. Die Funktion „translate_scancode“ übersetzt, wie oben im Kommentar angegeben, die Scancodes in interne Keycodes der Code dazu findet sich ebenfalls im tyndur-Repositoryhttp://git.tyndur.org/?p=tyndur.git;a=blob;f=src/modules/kbc/sc2kc.c. Es handelt sich dabei aber nur um eine mögliche Umsetzung und keineswegs um die einzig mögliche, hier muss man sich selbst überlegen wie das für den konkreten Anwendungsfall am komfortabelsten ist.

Du siehst lesen lohnt sich! :D
« Letzte Änderung: 30. May 2013, 21:55 von Martin Erhardt »

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 30. May 2013, 22:10 »
translate_scancode in dem KBC Beispiel ist eine C Funktion wie jede andere.
Natürlich musst du die selber deklarieren und definieren.

Und im Artikel steht ausdrücklich:
Zitat
Dieses Codestück unternimmt genau die oben beschriebenen Schritte. Die Funktion „translate_scancode“ übersetzt, wie oben im Kommentar angegeben, die Scancodes in interne Keycodes der Code dazu findet sich ebenfalls im tyndur-Repositoryhttp://git.tyndur.org/?p=tyndur.git;a=blob;f=src/modules/kbc/sc2kc.c. Es handelt sich dabei aber nur um eine mögliche Umsetzung und keineswegs um die einzig mögliche, hier muss man sich selbst überlegen wie das für den konkreten Anwendungsfall am komfortabelsten ist.

Du siehst lesen lohnt sich! :lol:
Ja du hast recht!
Allerdings erhalte ich nach dem einfügen den Fehler wie vorher vom Compiler
Mineorbit
« Letzte Änderung: 30. May 2013, 22:24 von mineorbit »

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 31. May 2013, 11:05 »
Inzwischen funktioniert es halbwegs,
allerdings bekomme ich falsche Zeichen zurück.
#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) {
kprintf("kbc: Unbekannter Scancode: 0x%x (%d)\n", scancode, set); } 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;
    uint8_t keycode = 0;
    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);
 
    // Um einen Breakcode handelt es sich, wenn das oberste Bit gesetzt ist und
    // es kein e0 oder e1 fuer einen Extended-scancode ist
    if ((scancode & 0x80) &&
        (e1_code || (scancode != 0xE1)) &&
        (e0_code || (scancode != 0xE0)))
    {
        break_code = 1;
        scancode &= ~0x80;
    }
 
    if (e0_code) {
        // Fake shift abfangen und ignorieren
        if ((scancode == 0x2A) || (scancode == 0x36)) {
            e0_code = 0;
            return;
        }
 
        keycode = translate_scancode(1, scancode);
        e0_code = 0;
    } else if (e1_code == 2) {
        // Fertiger e1-Scancode
        // Zweiten Scancode in hoeherwertiges Byte packen
        e1_prev |= ((uint16_t) scancode <<;
        keycode = translate_scancode(2, e1_prev);
        e1_code = 0;
    } else if (e1_code == 1) {
        // Erstes Byte fuer e1-Scancode
        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);
    }
        // Zum Testen sollte folgendes verwendet werden:
 kprintf("%c",keycode);
        //Nach erfolgreichen Tests, könnte eine send_key_event Funtkion wie bei Týndur verwendet werden
}

 
Ich bedanke mich jetzt schon für eure Hilfe
Mineorbit
Edit:
Bis jetzt bin ich noch einmal das Tutorial durchgegangen, und alles bis auf die Funktion register_intr_handler ist fertig. Wo genau müsste ich diese Funktion einbauen, und wie müsste sie aussehen?
Ich danke schon jetzt ffür Antworten
Mineorbit
« Letzte Änderung: 01. June 2013, 09:59 von mineorbit »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 01. June 2013, 14:58 »
Die Funktion register_intr_handler bekommt eine Interruptnummer X und einen Zeiger auf eine Funktion übergeben. Sie trägt diesen Zeiger dann irgendwo (z.B. in ein Array) ein, sodass dein allgemeiner Interrupthandler die Funktion aufruft, wenn Interrupt X aufgetreten ist. Du kannst als Alternative auch erstmal keyboard_interrupt direkt aufrufen, wenn der Keyboard-IRQ (IRQ 1) ausgelöst wurde. Wir hatten dazu kürzlich erst was http://forum.lowlevel.eu/index.php?topic=3187.0

Wenn ich deinen Code richtig interpretiere, hast du bisher nur eine Funktion geschrieben, die den Scancode in einen "Keycode" übersetzt. Du musst noch den Keycode in ein Zeichen umwandeln. (Wenn du kein Fan von den týndur-Abstraktionen bist, kannst du auch den Scancode direkt in ein Zeichen umwandeln.)

Du musst also eine weiteres Array, ähnlich wie das bereits vorhandene Anlegen. Das musst du an den richtigen Stellen mit den zu den Keycodes gehörigen Zeichen füllen. Eine Tabelle gibt es z.B. hier http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html#ss1.4
Dieser Text wird unter jedem Beitrag angezeigt.

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 01. June 2013, 17:10 »
Danke Jidder,
sowas ähnliches hatte ich mir schon gedacht, nur wie mach ich dann dazu nochmal die Funktion die zu den keycodes die richtigen zeichen raus sucht und wie behebe ich diesen doppelzeichen fehler?
Mineorbit

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 01. June 2013, 18:00 »
char keycode_to_zeichen[] = {
 0 /* error */,
 0 /* ESC */,
 '1', '2', '3', '4', '5', '6', ...
 /* usw von dem link abtippen */
}

char zeichen_raussuchen(int keycode)
{
  // TODO: Fehlerbehandlung
  return keycode_to_zeichen[keycode];
}

Ich weiß nicht was du mit Doppelzeichenfehler meinst.
Dieser Text wird unter jedem Beitrag angezeigt.

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 02. June 2013, 15:25 »
Danke Jidder für deine Hilfe,
Mit dopplunsfehler meine ich ,dass ich den scancode und den keycode(oder was auch immer mir da an komischen zeichen für den kezcode ausgegeben wird) immer doppelt zurück  bekomme.
Ansonsten wenn ich deine Char einbinde, gibt mir der Compiler aus :

keyboard.c:14:13: error: subscripted value is neither array nor pointer nor vector
Ansonsten sehr großen Dank(Ich hätte nie gedacht, dass es überhaupt bei mir mit den irq's klappt)
Mineorbit



Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 02. June 2013, 15:33 »
Mit dopplunsfehler meine ich ,dass ich den scancode und den keycode(oder was auch immer mir da an komischen zeichen für den kezcode ausgegeben wird) immer doppelt zurück  bekomme.
Du bekommst beim Drücken und beim Loslassen der Taste jeweils einen IRQ. Wenn du dir den Code, den du da kopiert hast, genauer anschaust, siehst du, dass noch eine Variable break_code hast, die beim ersten mal 0 und beim zweiten mal 1 sein sollte.

Ansonsten wenn ich deine Char einbinde, gibt mir der Compiler aus :

keyboard.c:14:13: error: subscripted value is neither array nor pointer nor vector
Ich kann leider nicht hellsehen, deswegen weiß ich nicht wie dein Code jetzt aussieht. Aber ich sag einfach mal, dass mein Code nur zu Illustrationszwecken war, und du deinen eigenen schreiben solltest.
Dieser Text wird unter jedem Beitrag angezeigt.

mineorbit

  • Beiträge: 55
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 02. June 2013, 18:25 »
Danke Jidder für die Hilfe!
Das ganze funktioniert jetzt.
Hätte nur noch eine Frage:Wie packe ich das ganze an besten in eine funktion wie readf(); für meinen Userring?
Ich hatte mir das so gedacht, dass ebx im syscall ein boolean übergeben wird an das Kernel um eine read funktion im kernel ein zuleiten.
Bitte korigier mich wenn ich falsch liege.


Danke für die Hilfe
Mineorbit

 

Einloggen