Warten auf Tastendruck



  • Hallo,
    wie kann ich in C auf einen Tastendruck warten?
    Danke schonmal.
    MfG



  • getchar(), wenn Du eine Standardbibliothek zur Verfügung hast. Was ich aber nicht annehme, da Du im OS-Development-Forum schreibst.



  • ja, da hast du recht. aber vielleicht kann man die auch irgendwie einbinden?



  • eine Standardbibliothek muss man selber implementieren, wenn man sie noch nicht hat (für sein OS), einfach so einbinden geht afaik nicht



  • Und wie geht das?


  • Mod

    Das ist ein komplexer Vorgang. Man schreibt im user-Bereich Funktionen, z.B. getchar.

    char getchar()
    {
        char ret = 0;
        EVENT_t ev = event_poll(&ret, 1, enabledEvents ? EVENT_TEXT_ENTERED : EVENT_NONE);
    
        while (ev != EVENT_TEXT_ENTERED)
        {
            if (ev == EVENT_NONE)
            {
                waitForEvent(0);
            }
            ev = event_poll(&ret, 1, enabledEvents ? EVENT_TEXT_ENTERED : EVENT_NONE);
        }
        return (ret);
    }
    

    Über syscalls wird dies an den Kernel transportiert.

    EVENT_t event_poll(void* destination, size_t maxLength, EVENT_t filter)
    {
        EVENT_t ret;
        __asm__ volatile("call *_syscall" : "=a"(ret) : "a"(39), "b"(destination), "c"(maxLength), "d"(filter));
        return (ret);
    }
    

    syscall Nr. 39:

    EVENT_t event_poll(void* destination, size_t maxLength, EVENT_t filter)
    {
        task_t* task = currentTask;
    
        while (task->parent && task->type == THREAD && task->eventQueue == 0)
        {
            task = task->parent; // Use parents eventQueue, if the thread has no own queue.
        }
    
        if (task->eventQueue == 0 || task->eventQueue->num == 0) // Event handling disabled or no events available
        {
            return (EVENT_NONE);
        }
    
        event_t* ev = 0;
        mutex_lock(task->eventQueue->mutex);
    
        if (filter == EVENT_NONE)
        {
            ev = task->eventQueue->list->head->data;
        }
        else
        {
            for (dlelement_t* e = task->eventQueue->list->head; e != 0; e = e->next)
            {
                ev = e->data;
                if (ev->type == filter)
                    break; // found event
                else
                    ev = 0;
            }
        }
    
        if (ev == 0)
        {
            mutex_unlock(task->eventQueue->mutex);
            return (EVENT_NONE);
        }
    
        EVENT_t type = EVENT_NONE;
    
        if (ev->length > maxLength)
        {
            if(maxLength >= sizeof(size_t)) // Buffer is large enough to store at least the size of the event. Just issue EVENT_BUFFER_TO_SMALL event, leave event in queue.
            {
                *(uint32_t*)destination = ev->length;
                return (EVENT_BUFFER_TO_SMALL);
            }
    
            type = EVENT_BUFFER_TO_SMALL;
            if (ev->length > sizeof(ev->data)) // data do not fit in pointer
            {
                free(ev->data);
            }
        }
        else
        {
            type = ev->type;
    
            if (ev->length > sizeof(ev->data)) // data does not fit in pointer
            {
                memcpy(destination, ev->data, ev->length);
                free(ev->data);
            }
            else // Data fits in pointer: Optimization for small data, data saved in pointer itself
            {
                memcpy(destination, &ev->data, ev->length);
            }
        }
        task->eventQueue->num--;
        list_delete(task->eventQueue->list, list_find(task->eventQueue->list, ev));
        mutex_unlock(task->eventQueue->mutex);
        free(ev);
    
        return (type);
    }
    


  • danke erstmal

    aber, was bedeutet event_t? muss ich das erst definieren?



  • event_t gehört zum ganzen (recht komplexen) Event-System von PrettyOS,
    welches du auch erstmal haben müsstest.

    Man könnte das natürlich auch ohne dieses Event-System (rein mit Interrupts etc.) lösen.
    Ich kann aber grad auch nicht (mehr) sagen wie.



  • Vielleicht solltest Du erstmal einen Tastaturtreiber schreiben...


  • Mod

    OS Development ist nicht ganz einfach. Tastaturtreiber ist sicher die erste Priorität. Bei PrettyOS keyboard.c.



  • Sry, dass ich mich nicht mehr gemeldet habe, ich hatte keine Zeit. Trotzdem danke.
    Ich versuche jetzt irgentwie das hinzubekommen. Naja, wenn ich scheitere, frage ich euch nochmal.
    MfG


  • Mod

    Schau dir einfach mal den Tastatur-Treiber in PrettyOS an.


Anmelden zum Antworten