0
0
Power-electronicsHow-ToIntermediate · 4 min read

How to Reduce Interrupt Latency in Embedded C Efficiently

To reduce interrupt latency in embedded C, keep your Interrupt Service Routines (ISRs) short and fast, disable interrupts only when necessary, and use hardware features like priority levels. Also, avoid heavy processing inside ISRs and use volatile variables to ensure proper data handling.
📐

Syntax

Interrupt Service Routines (ISRs) are special functions triggered by hardware interrupts. They use specific syntax depending on the compiler and microcontroller. Typically, an ISR is declared with an attribute or keyword to mark it as an interrupt handler.

Key parts:

  • void ISR_name(void): Function signature for ISR.
  • __attribute__((interrupt)) or ISR() macro: Marks function as ISR.
  • volatile keyword: Used for variables shared between ISR and main code to prevent optimization issues.
c
void __attribute__((interrupt)) Timer_ISR(void) {
    // ISR code here
}
💻

Example

This example shows a simple timer interrupt that toggles an LED. The ISR is kept short to reduce latency. The main loop runs independently.

c
#include <stdint.h>
#include <stdbool.h>

volatile bool led_state = false;

void __attribute__((interrupt)) Timer_ISR(void) {
    led_state = !led_state;  // Toggle LED state
    // Clear interrupt flag here (hardware specific)
}

int main(void) {
    // Initialize timer and interrupts here
    while (1) {
        if (led_state) {
            // Turn LED on
        } else {
            // Turn LED off
        }
    }
    return 0;
}
⚠️

Common Pitfalls

Common mistakes that increase interrupt latency include:

  • Writing long or blocking code inside ISRs.
  • Disabling interrupts for too long in main code.
  • Not using volatile for shared variables, causing stale data.
  • Ignoring interrupt priorities, causing lower priority interrupts to delay higher priority ones.

Example of a wrong and right approach:

c
// Wrong: Long processing inside ISR
void __attribute__((interrupt)) ISR_wrong(void) {
    for (int i = 0; i < 100000; i++) {
        // Heavy processing
    }
}

// Right: Set flag in ISR, process in main
volatile bool flag = false;
void __attribute__((interrupt)) ISR_right(void) {
    flag = true;  // Just set flag
}

int main(void) {
    while (1) {
        if (flag) {
            flag = false;
            // Do heavy processing here
        }
    }
    return 0;
}
📊

Quick Reference

Tips to reduce interrupt latency:

  • Keep ISRs short and fast.
  • Use hardware interrupt priorities.
  • Disable interrupts only when absolutely necessary and for the shortest time.
  • Use volatile for shared variables.
  • Process heavy tasks outside ISRs using flags or queues.

Key Takeaways

Keep Interrupt Service Routines (ISRs) short and avoid heavy processing inside them.
Use hardware interrupt priorities to handle urgent interrupts faster.
Disable interrupts only briefly and only when necessary to avoid blocking.
Use volatile variables for data shared between ISRs and main code to prevent optimization issues.
Defer complex tasks from ISRs to the main loop using flags or buffers.