Interrupt Handling

This deserves its own page, it’s pretty important to understand how interrupts actually work under the hood.

Got a relatively good understanding through this conversation: https://chatgpt.com/share/0b335513-a083-4bc7-8802-a6133dc704da

Essentially, in each Instruction Cycle, there is an additional interrupt stage that is added. If an interrupt is pending, then the Interrupt Handler is executed.

Big Advantage

No special code or programmer attention required. Everything happens in hardware.

You can see the big advantage of interrupts in the diagram below.

  • In this case, since we are dealing with I/O, it is O

Read the detailed steps at p.41, but below is a high-level of how an interrupt is processed. Lots of similarities to Process Switch, since in both cases, we need to save the current context.

Step 4 is important to understand

Step 4: Pushing the PSW and the PC onto the control stack is to prepare to transfer control to the Interrupt Service Routine.

The diagram below also helps.

  • This was confusing for me to understand at first, but just look at the arrows and you’ll understand

The Stack Pointer points to the top of the stack. When we push onto the stack, what we’re doing is just storing values from the current set of registers, since they will (potentially) be overwritten by new values once we are inside the Interrupt Service Routine.

After the interrupt finishes executing, how is the program restored exactly?

Return from Interrupt (IRET or RETI Instruction): Once the ISR finishes processing the interrupt, the CPU uses a special instruction, often called IRET (short for Interrupt Return) in x86 architectures or RETI in some other architectures.

The IRET instruction is used to:

  • Restore the saved program counter (PC) from the stack (the one that was pushed onto the kernel stack when the interrupt occurred).
  • Restore other saved registers.
  • Return the CPU from kernel mode back to user mode (if applicable).
  • The IRET instruction informs the CPU that the ISR has completed, allowing the CPU to resume execution of the original process that was interrupted.

Multiple Interrupts

In a real system, there are multiple interrupts: I/O, timers, ADC, PWM settings, RS232, CAN, EEPROM, I2C, etc.

Interrupt during interrupt processing?

This can happen. How do we handle it? See below

Approach 1:

  • Disable interrupts in ISR
  • No priority information
  • Not useful for time critical elements

Approach 2:

  • Priorities for ISR
  • How to assign priorities
  • Finite number of priority levels

The most straightforward way is to simply have it done sequentially. But this ignores priority. Below is an example with priority.

What about the contest of an interrupt service rountine?

I think that can be stored on the Kernel Stack.