Interrupt handling is essential in embedded systems because it helps hardware and software communicate effectively. It allows the CPU to quickly respond to unexpected events, ensuring that urgent tasks are handled. When an interrupt happens, the CPU stops what it is doing, saves its current state, and runs a special piece of code called an interrupt handler. This process makes the system more responsive and uses resources better by reducing the need to check the status of devices constantly.

In this guide, we will look at the basics of handling interrupts, the different types of interrupts, and their priorities. We will also take a look at how they work in microcontrollers like the 8051, by giving you a clear understanding of this important topic in embedded systems.

What is Interrupt Handling?

It is an important process in computer systems, especially in embedded systems, that helps the CPU quickly respond to unexpected events. When an interrupt happens, it tells the CPU to stop what it is doing and run a special piece of code called an interrupt handler. The interrupt handling process includes four steps:

  • First, the CPU notices the interrupt;
  • Then, it saves the current state of the program;
  • Next, it runs the interrupt handler to deal with the event;
  • Finally, it restores the saved state to continue the original program.

This system ensures that urgent tasks, such as responding to hardware signals or handling time-sensitive jobs, are completed quickly, keeping the system efficient and responsive.

Types of Interrupts in Embedded Systems

In embedded systems, interrupt handling is essential for managing asynchronous events and ensuring real-time responsiveness. They are categorized based on their source, behavior, and handling mechanisms. Below is a detailed breakdown of the types of interrupts commonly encountered in embedded systems:

1. Hardware Interrupts

Generated by external devices or on-chip peripherals to signal events.

  • Examples:
    • External: Button press, sensor input, UART data reception.
    • Internal: Timer overflow, ADC conversion complete, watchdog timer reset.
  • Usage: Handle real-time events (e.g., reading sensor data, time-critical tasks).

2. Software Interrupts

Triggered intentionally by software via specific instructions (e.g., SWI in ARM, INT in x86).

  • Examples:
    • System calls (e.g., OS tasks).
    • Debugging breakpoints.
  • Usage: Facilitate controlled transitions to kernel mode or service routines.

3. Maskable Interrupts

  • In interrupt handling, it can be enabled/disabled via software (e.g., using sei [enable] or cli [disable] in AVR).
  • Examples: Most hardware interrupts (timers, GPIO).
  • Handling: Controlled by the Global Interrupt Enable (GIE) flag.

4. Non-Maskable Interrupts (NMI)

  • Cannot be disabled and must always be serviced immediately.
  • Examples: Critical failures (power loss, hardware faults, watchdog timer resets).
  • Usage: Handle emergencies requiring guaranteed CPU attention.

5. Fixed-Priority Interrupts

  • Predefined priority levels (e.g., ARM Cortex-M NVIC).
  • Behavior: Higher-priority interrupts preempt lower-priority ones.

6. Non-prioritized (Polled) Interrupts

  • All interrupts share the same priority.
  • Handling: Processed in the order they occur.

7. Edge-Triggered Interrupts

  • Activated by a transition (rising/falling edge) on a signal.
  • Examples: Button presses, and pulse detection.
  • Advantage: Avoids repeated triggering during the signal hold.

8. Level-Triggered Interrupt Handling

  • Activated by a sustained signal level (high/low).
  • Examples: UART data ready, continuous sensor alerts.
  • Risk: May retrigger if the interrupt flag is not cleared.
Comparison Table

Type

Source

Maskable?

Priority

Example Use Case

Hardware Interrupt

External/Internal

Yes (most)

Configurable

Sensor input, timer overflow

Software Interrupt

CPU instruction

Yes

Fixed/Configurable

System calls

NMI

Critical hardware

No

Highest

Power failure

Exception

CPU error

No

High

Division by zero

Edge-Triggered

Signal transition

Yes

Depends on system

Button press

Level-Triggered

Sustained signal

Yes

Depends on system

UART data ready

Key Considerations
  • ISR Design: Keep Interrupt Service Routines (ISRs) short to avoid latency.
  • Atomicity: Protect shared data between ISRs and main code (e.g., disable interrupts during critical sections).
  • Nested Interrupts: Enable cautiously to prevent stack overflow or priority inversion.

Understanding these interrupt handling types and their characteristics is crucial for designing efficient, reliable embedded systems.

How Interrupt Handling Works?

In embedded systems is a critical mechanism that allows the processor to respond promptly to external or internal events. So, here is a structured explanation of how Interrupt handling works:

1. Overview

Interrupts enable the processor to temporarily halt its current task, handle an urgent event, and resume operations. This is more efficient than polling (continuously checking device status), as it reduces CPU overhead and ensures timely responses.

2. Key Components & Process Flow

a. Interrupt Occurrence

  • Source: Generated by hardware (e.g., timer overflow, sensor input) or software (e.g., system call).
  • Trigger: A peripheral or event asserts an interrupt request (IRQ) line.

b. Interrupt Acknowledgment

  • The processor finishes the current instruction, saves its state (program counter, registers), and disables further interrupts (unless nested interrupts are enabled).

c. Interrupt Vector Table (IVT)

  • A predefined memory table containing addresses of Interrupt Service Routines (ISRs). Each entry corresponds to a specific interrupt source.
  • The processor uses the interrupt type to index into the IVT and fetch the ISR address.

d. Interrupt Service Routine (ISR) Execution

  • ISR: A short, efficient function that handles the embedded systems interrupts. It typically:
    1. Clears the interrupt flag (to prevent retriggering).
    2. Performs minimal processing (e.g., reading sensor data, incrementing a counter).
    3. May trigger a deferred task (e.g., adding data to a queue for the main loop).

5. Context Restoration

  • After the ISR completes, the processor:
    1. Restores the saved state (registers, program counter).
    2. Re-enables interrupts (if disabled).
    3. Resumes the original task.

3. Interrupt Management

  • Enabling/Disabling in Interrupt Handling:
    • Global Interrupt Enable (GIE): Master switch for all interrupts.
    • Peripheral-Specific Enable: Individual control for each interrupt source (e.g., UART, ADC).
  • Prioritization: Higher-priority interrupts can preempt lower-priority ones (if supported by the hardware, e.g., NVIC in ARM Cortex-M).
  • Nested Interrupts: Some systems allow ISRs to be interrupted by higher-priority IRQs, requiring careful state management.

4. Types of Interrupts

  • Hardware Interrupts: External events (e.g., button press, UART data received).
  • Software Interrupts: Triggered by software instructions (e.g., system calls).
  • Non-Maskable Interrupts (NMI): Critical events (e.g., power failure) that cannot be disabled.

5. Best Practices of Embedded Systems Interrupt Handling

  • Keep ISRs Short: Lengthy ISRs delay other interrupts. Defer complex tasks to the main loop.
  • Atomic Operations: Ensure shared data between ISRs and main code is accessed atomically (e.g., via disabling interrupts temporarily).
  • Edge vs. Level Triggers: Configure peripherals appropriately (e.g., edge-triggered for button presses, level-triggered for continuous signals).

6. Hardware Involvement

  • Interrupt Controller: This device manages IRQ routing, prioritization, and masking (e.g., NVIC in ARM, PIC in AVR).
  • Peripheral Registers: Flags (e.g., TIMER1_IFG) indicate interrupt status and are cleared in the ISR.

7. Architecture Variations

  • While the core concepts apply universally, specifics (e.g., IVT location, register names, priority levels) vary across architectures (e.g., AVR vs. ARM vs. PIC).

Example Workflow

  1. Button Press: A GPIO pin triggers an interrupt.
  2. Processor: Saves context, and jumps to the GPIO ISR via the IVT.
  3. ISR: Reads button state, sets a flag for the main loop, clears the interrupt.
  4. Resume: The processor restores context and continues executing the main program.

Interrupt Priorities

In embedded systems, multiple interrupts can pop up at the same time or close together. To handle this chaos, we assign priorities to make sure the most important tasks get sorted out first. There are a couple of ways to set these priorities:

With Fixed Priority, each interrupt has a set priority level, so the CPU always deals with the higher-priority ones first. On the other hand, Dynamic Priority allows the priority levels to change depending on what's happening in the system, giving us more flexibility in managing everything.

Interrupt Handling in 8051 Microcontroller

In the 8051 microcontroller is a fundamental feature for managing real-time events and peripheral interactions. The 8051 supports 5 interrupt sources, each with unique characteristics and handling mechanisms. Below is a detailed breakdown:

1. Interrupt Sources in 8051

The 8051 has 5 interrupt sources, each mapped to a specific vector address in memory:

Interrupt Source

Vector Address

Flag

Trigger Condition

External Interrupt 0 (INT0)

0x0003

IE0 (TCON.1)

Low-level or falling edge on P3.2 pin.

Timer 0 Overflow

0x000B

TF0 (TCON.5)

Timer 0 overflows from 0xFF to 0x00.

External Interrupt 1 (INT1)

0x0013

IE1 (TCON.3)

Low-level or falling edge on P3.3 pin.

Timer 1 Overflow

0x001B

TF1 (TCON.7)

Timer 1 overflows from 0xFF to 0x00.

Serial Port Interrupt

0x0023

RI/TI (SCON)

Serial data received (RI) or transmitted (TI).

2. Interrupt Control Registers

a. Interrupt Enable (IE) Register

In interrupt handling, it controls which interrupts are enabled. Bit structure:

Bit

7 (EA)

6

5 (ET2)

4 (ES)

3 (ET1)

2 (EX1)

1 (ET0)

0 (EX0)

Function

Global Enable

-

Timer 2*

Serial

Timer 1

INT1

Timer 0

INT0

EA (Global Enable): Must be set to 1 to enable any interrupt.

  • EX0/EX1: Enable INT0/INT1.
  • ET0/ET1: Enable Timer 0/1 interrupts.
  • ES: Enable serial port interrupt.

Note: Timer 2 interrupt is available only in 8052 variants.

b. Interrupt Priority (IP) Register

Assigns high (1) or low (0) priority to interrupts.

Bit

7

6

5 (PT2)

4 (PS)

3 (PT1)

2 (PX1)

1 (PT0)

0 (PX0)

Function

-

-

Timer 2*

Serial

Timer 1

INT1

Timer 0

INT0

  • Higher-priority interrupts can preempt lower-priority ones.
  • If two interrupts of the same priority occur, the natural order is:
    INT0 → Timer 0 → INT1 → Timer 1 → Serial Port.

3. Interrupt Handling Process

  • Interrupt Trigger:
      • An interrupt flag (e.g., TF0, IE0) is set by hardware.
  • Interrupt Acknowledgment:
      • The 8051 completes the current instruction.
      • Saves the Program Counter (PC) to the stack.
      • Disables further interrupts (unless nested interrupts are configured).
  • Jump to ISR:
      • The processor jumps to the corresponding vector address (e.g., 0x000B for Timer 0).
      • Typically, a LJMP or AJMP instruction is placed here to redirect to the ISR code.
  • Execute ISR:
      • The Interrupt Service Routine (ISR) performs the required task (e.g., reset a timer, and read serial data).
      • Critical Step: Clear the interrupt flag (e.g., TF0 = 0) to avoid retriggering.
  • Return from ISR:
    • Use the RETI instruction to restore the PC and re-enable interrupts.

4. Edge vs. Level Triggering (External Interrupts)

  • Edge-Triggered (IT0/IT1 = 1 in TCON register):
    Interrupt occurs on a falling edge (high-to-low transition) at INT0/INT1.
    • Advantage: Avoids repeated triggers if the signal remains low.
  • Level-Triggered (IT0/IT1 = 0):
    An interrupt occurs when INT0/INT1 is held low.
    • Risk: Interrupt retriggers if the pin remains low after ISR execution.

5. Example Code of Interrupt Handling (Timer 0 Interrupt)

 


ORG 0000H
LJMP MAIN       ; Jump to the main program

ORG 000BH       ; Timer 0 ISR vector address
LJMP TIMER0_ISR ; Redirect to ISR

ORG 0030H
MAIN:
  MOV TMOD, #01H ; Timer 0 in Mode 1 (16-bit)
  MOV TH0, #0FCH ; Load initial value for 1ms delay 
  MOV TL0, #018H
  SETB EA        ; Enable global interrupts
  SETB ET0       ; Enable Timer 0 interrupt
  SETB TR0       ; Start Timer 0
  SJMP $         ; Wait indefinitely

TIMER0_ISR:
  CLR TF0        ; Clear Timer 0 flag
  MOV TH0, #0FCH ; Reload timer
  MOV TL0, #018H
  RETI           ; Return from ISR

     

6. Best Practices

  1. Short ISRs: Keep ISRs minimal to reduce latency for other interrupts.
  2. Flag Management: Always clear interrupt flags (e.g., TF0, RI, TI) in the ISR.
  3. Shared Data: Use atomic operations or disable interrupts briefly when accessing shared variables.
  4. Nested Interrupts: Use cautiously (re-enable EA inside ISR) to avoid stack overflow.

7. Common Pitfalls

  • Forgetting to clear interrupt flags (causing infinite retriggering).
  • Stack overflow due to deep nested interrupts.
  • Using RET instead of RETI (fails to re-enable interrupts).

How to Write an Interrupt Handler for 8051?

Creating an interrupt handler for the 8051 involves defining a function that will execute when a specific interrupt occurs. This process is part of interrupt handling. Here is a simple example of how to write an interrupt handler for Timer 0 overflow:

 


#include 
void Timer0_ISR(void) interrupt 1 {
    // Code to handle Timer 0 overflow
    // For example, increment a counter or toggle an LED
    TH0 = 0xFC; // Reload Timer 0 high byte
    TL0 = 0x66; // Reload Timer 0 low byte
}
void main(void) {
    // Configure Timer 0
    TMOD = 0x01; // Timer 0 in mode 1 (16-bit timer)
    TH0 = 0xFC;  // Load Timer 0 high byte
    TL0 = 0x66;  // Load Timer 0 low byte
    TR0 = 1;     // Start Timer 0
    EA = 1;      // Enable global interrupts
    ET0 = 1;     // Enable Timer 0 interrupt

    while (1) {
        // Main loop
    }
}


     

In this example, the Timer0_ISR function is defined as the interrupt service routine (ISR) for Timer 0. The interrupt 1 keyword indicates that this function will be called when Timer 0 overflows. The main function sets up Timer 0 and enables interrupts.

Best Practices for Interrupt Handling

To handle interrupts effectively in embedded systems, follow these simple best practices:

  1. Keep ISRs Short: Make the code in the interrupt handler as brief as possible. This helps the CPU return to the main program quickly.
  2. Avoid Blocking Calls: Don’t use commands that make the program wait (like delays or waiting for input) inside an interrupt handler. This can cause important interrupts to be missed.
  3. Use Flags for Processing: Instead of doing a lot of work in the interrupt handler, set a flag to signal that something needs to be done. The main program can check this flag and handle the work later.
  4. Prioritize Interrupts Wisely: Give different priorities to interrupts based on how urgent they are. This way, the most important tasks get handled first.
  5. Test Thoroughly: Test the interrupt handling in different situations to make sure everything works correctly and that no interrupts are missed.

These practices help ensure that your embedded system responds well to interrupts!

Conclusion

In embedded systems, interrupt handling is a critical mechanism that allows a processor to respond quickly to external and internal events. Interrupts improve system efficiency by enabling devices to execute multiple tasks without constant CPU intervention. They are broadly classified into hardware interrupts (triggered by external devices) and software interrupts (initiated by programs), ensuring real-time responsiveness in embedded applications.

Embedded system engineers must understand interrupt handling, real-time operating systems (RTOS), and microcontroller programming. A structured Embedded Systems course can provide hands-on experience in interrupt-driven programming, peripheral interfacing, and system optimization, helping professionals develop efficient and reliable embedded applications.

Frequently Asked Questions (FAQs)
Q. What is the interrupt handling mechanism in a microprocessor?

Ans. The handling mechanism in a microprocessor is the process of noticing an interrupt, saving what the CPU is doing, running the code to handle the interrupt, and then going back to normal tasks.

Q. What is an interrupt handler in a microcontroller?

Ans. An interrupt handler in a microcontroller is a special function that runs when an interrupt happens. It has the code needed to deal with the specific event that caused the interrupt.