Autor Thema: Tastatur Eingabe  (Gelesen 6143 mal)

evildrno

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« am: 24. November 2011, 19:10 »
Hallo an Alle, hab jetzt gerade meinen ersten lowlevel "Kernel" programmiert, wenn man des so nennen kann XD. Kann halt nen String ausgeben, bin also noch bei HelloWorld...

Naja schön wäre es jetzt natürlich auch ne Eingabe machen zu können, dann kann man ja schon sein erstes "Jump n run" machen, oder nen Taschenrechner...

Hab jetzt aber keinen Plan wie (in C so weit wie es geht, bzw. halt Inline-Assembler). Hab nach der suche mit der SuFu gelesen, dass man dazu den PIC programieren muss und nen IDP Eintrag machen muss. Da steig ich aber noch net so richtig durch. Gibts da evtl. gerade dafür n tutorial, bzw. kann mir da einer das "vorprogrammieren" und erklären?

Ich weiß noch, dass ich vor 2 Jahren mal sowas auf nem RISC glaub war n MIPS in Assembler gemacht hab. Also per Polling geschaut ob der Tastatur-Controller was hat, und wenn ja in den Speicher geschrieben und dann halt noch addiert. Da brauchte ich aber keine interupt Tabelle usw. geht das für den x86 und C (mit Inline-Assembler) nicht ähnlich einfach, gut polling ist nicht schön, aber fürs erste langts... Wenn Ja (also es geht) kann mir da jemand ne Methode machen, mit der ich z.B einfach die angelegte taste in n Int bekomm, oder so, den rest bekomm ich dann hin.

So falls mir da jemand Helfen könnt (was vorprogrammiren wäre am besten, aber auch Denkanstöße fänd ich klasse) wäre das super. Danke schön

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 24. November 2011, 19:25 »
Hallo,


fürs erste geht das wimre auch mal mit Polling, aber das ist wirklich nur eine Übergangsnotlösung.
Ein gutes Tutorial gibt es da http://www.lowlevel.eu/wiki/OS-Dev_f%C3%BCr_Einsteiger, und dann einfach unten in der Navigationsleiste zum nächsten Abschnitt weiter klicken.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 24. November 2011, 21:00 »
Hallo,

PIC und IDT musst du nur benutzen, wenn du Interrupts haben möchtest.
Pollen kannst du den Tastaturcontroller auch, wie der funktioniert, steht z.B. hier. Du guckst an Port 0x64 nach, ob Daten vorliegen und liest sie dann aus Port 0x60 aus.

Den Rest musst du selbst machen, vorprogrammieren gibt's hier nicht. :evil:

Gruß,
Svenska

evildrno

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 24. November 2011, 22:41 »
Ok, habs dann hin bekommen. Mit ein wenig Assembler wars dann auch kein prob. Aber bis ich den Inline-Assembler verstanden hab  :? Naja und gerade für ne Methode wie scanf oder getchar is ja polling durchaus ok ^^.
 Wegen dem Code vorprogramieren: Ich mein des is halt geschickt ums mal prinzipel besser zu verstehen anhand eines bsp. Ich mein umprogrammieren hätt ichs ja so oder so müssen. Wenn ichs fertig hab und n getchar dann richtig tut poste ichs hier ggf. für die dies auch wissen wollen und net gleich hin bekommen.

evildrno

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 27. November 2011, 18:25 »
So ich hab die ganze Geschichte doch mit Interrupts gemacht (der Code is hauptsächlich vom Tut. hier).
Jetzt wäre es ganz cool wenn sich jemand das Anschauen könnt, also dies ist mein Interrupt-Handler und "readKeys" is auf 1 wenn ich grad in der "getc" also Einlesemethode (bleibt solange auf 1 bis Enter dabei war oder ende vom Buffer ereicht wurde) bin.
void handle_interrupt(struct cpu_state* cpu)
{

    if (cpu->intr <= 0x1f) {
        print("Exception %d, Kernel angehalten!");
        moveCursor(0,0);

        // TODO Hier den CPU-Zustand ausgeben

        while(1) {
            // Prozessor anhalten
            asm volatile("cli; hlt");
        }
    } else if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {
        if(cpu->intr == 33){    // Tastatur
            mprintf(byteToChar(key_ins),80*13,0x07);  //Nur ne Ausgabe wieviel Tastenanschläge bzw. Tastatur Interrupts es gab
            moveCursor(0,0);

            unsigned char flag;
            unsigned char input;

            flag = inb(0x64) & (0x01); //Hier ggf noch überprüfen ob flag auch wirklich gesetzt bevors weiter geht
            input = inb(0x60);
            new_checkKeys(flag, input);  //schreibt mir in ne bitmaske welche tasten gerade gedrückt sind
            if((readKeys > 0) && (input < 128))
                new_getLine_int(flag, input);  //ruft die methode auf welche nacheinander die Zeichen in den Buffer lädt
            key_ins++;

        } else
        if(cpu->intr == 32){    //timer
            mprintf(byteToChar(tim),80*12,0x07);  //Ausgabe von Timer Interrupt Anzahl -> Zeit seit dem das programm leuft
            moveCursor(0,0);
            tim++;                                              //und Variable hochzählen
        }

        if(readKeys > 0 ){     //--> Hier is die Frage ob man des so machen kann, also wenn readKeys auf 1 is, den Prozessor noch im Interrupt schlafen legen
            outb(0x20, 0x20);//     und warten bis neuer Interrupt kommt
            outb(0xa0, 0x20);

            asm volatile ("sti;hlt");
        }

        if (cpu->intr >= 0x28) {
            // EOI an Slave-PIC
            outb(0xa0, 0x20);
        }
        // EOI an Master-PIC
        outb(0x20, 0x20);

    } else {
        print("Unbekannter Interrupt");
        while(1) {
            // Prozessor anhalten
            asm volatile("cli; hlt");
        }
    }
}

So Ist das ok, Oder wird da der Stack zugemüllt da bei einem Interrupt (z.b. durch PIT) der alte Interrupt noch nicht beendet wird, also Register wieder herstellen usw. Und dann wird ja wieder auf den neuen Interrupt gewartet, der ggf. wieder nicht zu ende kommt usw.
Also seinen Sinn des polling zu vermeiden tuts schon, also cpu auslastung ist so minimal.

Wenn das so schwachsinn is, wie kann ich des anderes machen.
« Letzte Änderung: 27. November 2011, 19:03 von evildrno »

evildrno

  • Beiträge: 14
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 27. November 2011, 19:07 »
Oh man, man kann ja auch Interrupts maskieren, damit sollte es doch dann gehen, oder?

 

Einloggen