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
volatilekeyword 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.