Keyboard input / processing architecture

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
LukeyTheKid
Posts: 17
Joined: Fri Jun 12, 2020 7:53 am
Libera.chat IRC: lukeythekid

Keyboard input / processing architecture

Post by LukeyTheKid »

I've implemented all of the interrupt handler, PS/2 controller logic in order to get keyboard input, and I am successfully receiving the proper scan codes when I type. After reading through some forum posts, I had a couple of questions regarding to to "properly" deal with keyboard input in way that will be efficient and maintainable.

My first question relates to processing the scan code data I receive from a key press/release. For example:
  • * Press the 'G' key
    * Receive the scan code 0x34
    * Release the 'G' key
    * Receive the scan code 0xF0 0x34
In my initial implementation, I just wanted to get things going, so I just read a byte and printed it in my ISR. With that implementation, IRQ1 seems to fire once for each scan code byte until everything is read (in the above example, IRQ1 fires 3 times). Is this the normal way to handle multi-byte scan codes, or should I be trying to process all of the data at once (e.g. for a release, read 2 bytes from port 0x60 in the ISR)? If I'm processing all of the data at once, I guess I would have to use bit 0 of the status register to determine whether there is more data?

--------------------------

My second question relates to where and when to manage the input data from the keyboard. For one thing, I have read that it is not good practice to have too much logic in the ISR, and for another thing, I am guessing in the future I will want to do more sophisticated input handling than just echoing the keyboard input. One approach I have read is to simply take whatever scan code we received, append it to a buffer somewhere, and have a dedicated thread/task that deals with this data separately. Right now I just have a simple kernel, no process/thread support, so at this stage my approach would have to be a bit primitive - just have the kernel main loop to process/output the keyboard input.

Mostly looking for an answer to the first question before I proceed, but also very curious to see people's approach for the actual input processing. Thank you in advance!
Octocontrabass
Member
Member
Posts: 5885
Joined: Mon Mar 25, 2013 7:01 pm

Re: Keyboard input / processing architecture

Post by Octocontrabass »

LukeyTheKid wrote:Is this the normal way to handle multi-byte scan codes
It's the only way, if you want it to work correctly.
LukeyTheKid wrote:One approach I have read is to simply take whatever scan code we received, append it to a buffer somewhere, and have a dedicated thread/task that deals with this data separately.
I like the approach of using IRQs to wake a sleeping user-mode driver thread, which handles anything critical (reading a byte from the keyboard controller, for example) and then performs a system call to acknowledge the IRQ. The thread can remain awake to handle lower-priority work (dispatching a "key press" message, for example) before sleeping to wait for the next IRQ.

I'm not sure if all the context switches for shared IRQs will be a problem.
LukeyTheKid
Posts: 17
Joined: Fri Jun 12, 2020 7:53 am
Libera.chat IRC: lukeythekid

Re: Keyboard input / processing architecture

Post by LukeyTheKid »

It's the only way, if you want it to work correctly.
Okay great, thanks. I was kind of hoping this was the answer; trying to handle different cases for different scan code lengths seemed like a headache.
I like the approach of using IRQs to wake a sleeping user-mode driver thread, which handles anything critical (reading a byte from the keyboard controller, for example) and then performs a system call to acknowledge the IRQ. The thread can remain awake to handle lower-priority work (dispatching a "key press" message, for example) before sleeping to wait for the next IRQ.
That's an interesting approach - would you mind sharing a link to that code? I don't even have userspace set up yet, but I'm curious to see what that looks like.
I'm not sure if all the context switches for shared IRQs will be a problem.
Problem performance-wise, or something else? It sounds like a lot if a context switch occurs happens on every single IRQ.
Post Reply