When I hold down a key on my keyboard, a continuous stream of characters is generated and is displayed on the text editor, Now since pressing a key is a hardware interrupt, so does holding down a key continuously generates interrupt signals and does CPU constantly keeps acknowledging those ? or something else happens ?

  • $\begingroup$ This surely depends on what hardware and what operating system is being used. $\endgroup$ – David Richerby Sep 9 '18 at 10:19

TL;DR: No.

It depends on the OS and the keyboard. I'll show you how to determine this yourself on a Linux machine. I'm using Ubuntu 16.04 on an x86 processor. So if you are using a fairly modern version of Linux and an x86 processor, then the steps will be pretty much the same. I have a USB keyboard (and mouse) and almost everyone else does.

Open a new terminal and execute the following command:

watch -n0.5 "cat /proc/interrupts"

This enables you to monitor hardware interrupts in real time. Examine the last column and look for the lines that contain ehci_hcd:usbN where N is some small number. On my system, there are two such line:

            CPU0       CPU1       CPU2       CPU3 
 16:         17          3          0          9  IR-IO-APIC  16-fasteoi   ehci_hcd:usb1 
 23:         88      72272     101007    1327899  IR-IO-APIC  23-fasteoi   ehci_hcd:usb2

The first column shows the interrupt request signal number (IRQ). It identifies a physical bus on the motherboard that is used by the I/O device to interrupt the processor. The four columns in the middle show the number of interrupts handled by each core. There are four (logical) cores on my system. Notice how the overall number of interrupts from IRQ 23 is very large while the number of IRQ 16 interrupts is almost zero. This is a strong indication that the keyboard and mouse both use IRQ 23 to send interrupts to the processor. In general, though, the mouse and keyboard may use different IRQs depending on the USB port they are connected to. Some USB ports may share the same IRQ line1.

Now you can observe what happens to the interrupt counts when using the keyboard. Hold the mouse still (so that the mouse does not generate any interrupts) and press some keys on your keyboard. When a keyboard key is pressed, the interrupt count on one of the CPUs will increase by exactly one. When a key is released, the interrupt count will also increase by one. In addition, you can see that, while the key is held down, the interrupt count does not change. Therefore, the keyboard does not send interrupts for the key held down. Instead, Linux uses a software keyboard repeat mechanism, by default, for USB keyboards. As long as the keyboard has not yet sent an interrupt indicating that the key has been released, Linux knows that it is held down.

Software keyboard repeat is implemented by using a timer interrupt. There are two parameters involved, both are configurable. The first is called the typematic repeat rate (also called autorepeat rate), which specifies the rate at which the keydown event should be repeated in terms of the number of characters per second. The second is called the typematic delay, which specifies how long a key must be held, in milliseconds, before it begins to repeat. You can print the current values of these parameters using sudo kbdrate. On modern versions of Linux, it prints:

Typematic Rate set to 10.9 cps (delay = 250 ms)

You can also modify these parameters using the same tool, and then observe the effects using /proc/interrupts as discussed above.

Since software keyboard repeat relies on the timer interrupt, it can support a wider range of typematic repeat rates and shorter typematic delays. This is in contrast to hardware keyboard repeat, which is the default mode for AT and PS/2 keyboards in old versions of Linux. People who used to suffer issues from hardware keyboard repeat were advised to use atkbd.softrepeat=1. Most keyboards are configurable regarding keydown repeat behavior.

For more information, you can refer to /include/linux/input.h and /include/linux/input.c of the Linux source code as a starting point.

Footnote 1:

You can determine with certainty which IRQ line the USB keyboard and mouse are connected to by executing the following command:

lsusb -v

This will print a list of all USB ports and controllers on the PCIe interconnect. On my system, all USB ports are either on Bus 001 or Bus 002. In /proc/interrupts, these are named ehci_hcd:usb1 and ehci_hcd:usb2, respectively. So, for example, if lsusb tells you that the keyboard is on Bus 001, then the keyboard uses IRQ 16. When a key is pressed or released, the scan code of the key is simply stored in the keyboard buffer and the keyboard controller then raises an interrupt to one of the CPUs (as specified by I/O APIC interrupt affinity). Then the target CPU gets interrupted, calls the interrupt handler mapped to the IRQ, which in turn reads the scan code from the keyboard controller buffer and stores it into the kernel's keyboard buffer for further processing.

  • $\begingroup$ Awesome answer @Hadi Brais. Very detailed! Please could you visit my SO profile and contact me, I'd like to talk to you about an opportunity to build something (assuming it is technically possible!) $\endgroup$ – rmcsharry Nov 16 '20 at 6:50
  • $\begingroup$ @rmcsharry Thanks, dude. I'm currently busy with certain projects and I don't think I dedicate a significant amount of my time on a new project. BTW, my profile has a link to my blog and there you can find my email address. $\endgroup$ – Hadi Brais Nov 17 '20 at 0:33
  • $\begingroup$ ok thanks, I emailed you. Simple question for now, just needs a yes or no answer :) $\endgroup$ – rmcsharry Nov 17 '20 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.