0
0
Power-electronicsHow-ToBeginner · 3 min read

How to Protect Shared Resources from Interrupts in Embedded C

To protect shared resources from interrupts in embedded C, temporarily disable interrupts using __disable_irq() and __enable_irq() around the critical section. This prevents interrupt handlers from accessing the resource simultaneously, avoiding data corruption.
📐

Syntax

Use these functions to disable and enable interrupts around the critical code that accesses shared resources:

  • __disable_irq(); - Disables all interrupts.
  • __enable_irq(); - Enables interrupts again.

Place the critical code between these calls to protect shared data.

c
void access_shared_resource() {
    __disable_irq();  // Stop interrupts
    // Critical section: access or modify shared resource
    __enable_irq();   // Allow interrupts again
}
💻

Example

This example shows a shared counter variable updated safely by disabling interrupts during the update to avoid race conditions.

c
#include <stdio.h>

volatile int shared_counter = 0;

void __disable_irq() {
    // Simulate disabling interrupts (platform-specific in real code)
}

void __enable_irq() {
    // Simulate enabling interrupts
}

void increment_counter() {
    __disable_irq();
    shared_counter++;  // Critical section
    __enable_irq();
}

int main() {
    printf("Counter before: %d\n", shared_counter);
    increment_counter();
    printf("Counter after: %d\n", shared_counter);
    return 0;
}
Output
Counter before: 0 Counter after: 1
⚠️

Common Pitfalls

Common mistakes when protecting shared resources include:

  • Not disabling interrupts long enough, causing partial updates.
  • Disabling interrupts for too long, which can delay important interrupt handling.
  • Forgetting to re-enable interrupts, causing system lockup.
  • Using non-atomic operations on shared variables without protection.

Always keep the critical section as short as possible and ensure interrupts are re-enabled.

c
/* Wrong way: interrupts not disabled, risk of data corruption */
void unsafe_increment() {
    shared_counter++;  // Not protected
}

/* Right way: interrupts disabled during update */
void safe_increment() {
    __disable_irq();
    shared_counter++;
    __enable_irq();
}
📊

Quick Reference

Tips to protect shared resources from interrupts:

  • Use __disable_irq() and __enable_irq() to bracket critical sections.
  • Keep critical sections short to avoid interrupt latency.
  • Use volatile keyword for shared variables accessed in interrupts.
  • Consider atomic operations or mutexes if supported by your platform.

Key Takeaways

Disable interrupts briefly around shared resource access to prevent data corruption.
Always re-enable interrupts after the critical section to avoid system lockup.
Keep critical sections as short as possible to maintain system responsiveness.
Use the volatile keyword for variables shared with interrupt routines.
Avoid complex operations inside critical sections to reduce interrupt blocking time.