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 ?
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.c of the Linux source code as a starting point.
You can determine with certainty which IRQ line the USB keyboard and mouse are connected to by executing the following command:
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: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.