Interrupts: Breaks that Make Your PC Run

Have you ever noticed how many times you press a key on the keyboard, or how often you click your mouse? Ever wondered how the PC is able to keep track of all these inputs and handle them? This is closely related with interrupts. We interrupt our PC numerous times in a day, without realising what goes on behind the scenes. This article explains the concept of interrupts.

In simple English, an interrupt means to cause, or make a break in the continuity or uniformity of a course or a process. Similarly, in computer science, an interrupt is a signal from hardware or software, indicating the need for the CPU’s attention; i.e., interrupts provide a way to get the CPU’s attention.

Let’s look at the example of your keyboard. It connects to the PC via a keyboard controller. Whenever you press a key, the keyboard sends the keyboard controller a scan code, which is then passed by the keyboard controller to the CPU (see Figure 1).

Figure 1: Keystroke causes interrupt

The keyboard controller can hold only a single keystroke. Therefore, the keyboard controller must be freed before the next keystroke arrives. The keystroke is passed to the CPU by putting it in the keyboard buffer. So, the keyboard controller keeps on passing the keystroke input to the CPU, but how does the CPU attend to it?

The CPU is not at the disposal of the keyboard controller; it is usually busy doing several other operations. So, we need some mechanism to indicate to the CPU that a keystroke has arrived. How is this done? There are two approaches to making sure that the CPU pays attention:

Polling-based

Interrupt-based

The polling-based system

We can think of polling as akin to having a phone without the capability to ring aloud. With such a phone, you would have to periodically pick up the receiver to check if there is a call coming through. In a similar fashion, in a polled system, the CPU periodically suspends its tasks and asks the keyboard controller if there is a keystroke (see Figure 2).

Figure 2: Polling-based interrupt handling

If there is a keystroke, it forwards it to the CPU (Figure 3). If there is no keystroke (Figure 4), it conveys this to the CPU, and the latter continues with its operations. In either case, the CPU then returns to what it was doing. After some time has passed, it again checks the keyboard controller.

Figure 3: Keystroke passed to the CPU

Figure 4: No keystroke for CPU

Interrupt-based systems

With an interrupt-based system, the CPU is designed to accept interrupts — input signals from other circuits that ask it to pay attention, as depicted in Figure 5.

Figure 5: Interrupt-based approach

Examining the same example that we discussed earlier, when the keyboard controller receives a keystroke, it places a signal for the CPU, asking it to pay attention. The CPU senses the interrupt and puts its current work aside, signalling the keyboard controller that it’s ready to accept the keystroke.

In contrast to the analogy of a telephone without a ring, the interrupt signal is similar to a telephone’s ring. We can continue with our work, without bothering to check every now and then since the bell notifies us of an incoming call.

As you would agree, polling requires less support from hardware, but the CPU spends a good amount of time in checking if any of the polled peripherals need attention. Thus, an interrupt-based system is usually preferred over a polling-based system.

Broadly, interrupts are classified into hardware interrupts and software interrupts.

Figure 6: Types of interrupts

Software interrupts

A software interrupt is one that’s generated within a processor by executing an instruction. Examples of software interrupts are system calls (like fork and kill in UNIX).

Hardware interrupts

A hardware interrupt is a signal that is created and sent to the CPU because of some action in/on a hardware device. For example, keystrokes and mouse movements cause hardware interrupts. A hardware interrupt causes the processor to save its state of execution via a context switch, and begin execution of an interrupt handler.

Software interrupts are usually implemented as instructions in the instruction set, which cause a context switch to the interrupt handler, similar to a hardware interrupt.
Hardware interrupts comprise two major classes:

Non-maskable interrupts (NMI): This is caused by some serious hardware problem like a memory error. Such an interrupt cannot be ignored or suppressed. This is quite obvious, since incorrect or malfunctioning hardware must be rectified before any other processing can be done reliably. This kind of interrupt cannot be delayed or rejected.

Maskable interrupts: This is a hardware interrupt that may be delayed, or rejected by setting a bit in an interrupt mask register’s (IMR) bitmask.

When an interrupt occurs

An interrupt causes the CPU to stop executing the current program, and start executing a special piece of code, called an interrupt handler, or interrupt service routine (ISR). The ISR does some work, and then resumes the interrupted program. Each interrupt has its own Interrupt Service Routine, which is looked up via the Interrupt Vector Table.

Interrupt type

Address of ISR

INT 1

Address (ISR 1)

INT 2

Address (ISR 2)

INT 3

Address (ISR 3)

INT 4

Address (ISR 4)

:
:

:
:

INT n

Address (ISR n)

This is a table of interrupt vectors, which associate an interrupt handler with an interrupt request. Interrupt vector tables contain the memory addresses of interrupt handlers. When an interrupt is generated, the processor saves its execution state via a context switch, and begins execution of the interrupt handler at the interrupt vector.

In my next article I will discuss how the context switch is carried out during an interrupt, and what we need to consider while designing an Interrupt Service Routine.

Glossary

Context switch: A context switch is the computing process of storing and restoring the state of a CPU (the context) such that multiple processes can share a single CPU’s resources.

Interrupt handler: This is also known as an Interrupt Service Routine (ISR). It is a subroutine whose execution is triggered by the reception of an interrupt.

The author is a senior software engineer with a considerable amount of experience in the design, development and quality validation of System Software Tools (compilers/assemblers/device drivers) for embedded systems. She has also been a mentor/trainer for compiler development, following good practices and maintaining quality.