Volatile variables tell the compiler that their value can change anytime, especially in interrupt routines. This prevents wrong assumptions and keeps the program working correctly.
Volatile variables in ISR context in Embedded C
volatile type variable_name;The keyword volatile tells the compiler not to optimize or cache the variable.
Use it for variables that can change unexpectedly, like in ISRs or hardware registers.
flag that might change in an ISR.volatile int flag;volatile char data_ready = 0;This program shows a volatile variable data_ready that is changed inside a simulated ISR function. The main program checks this variable before and after the ISR call.
#include <stdio.h> #include <stdbool.h> volatile bool data_ready = false; // Simulated ISR that sets data_ready void ISR_simulator() { data_ready = true; } int main() { printf("Before ISR: data_ready = %d\n", data_ready); ISR_simulator(); // Simulate interrupt if (data_ready) { printf("After ISR: Data is ready!\n"); } else { printf("After ISR: Data not ready.\n"); } return 0; }
Without volatile, the compiler might optimize and assume the variable does not change, causing bugs.
Always declare variables shared between ISRs and main code as volatile.
Volatile tells the compiler a variable can change anytime, so it must always read it fresh.
Use volatile for variables changed in interrupts or hardware.
This helps avoid bugs caused by compiler optimizations.
Practice
volatile?Solution
Step 1: Understand the role of
Thevolatilevolatilekeyword tells the compiler that the variable's value can change at any time, outside the normal program flow.Step 2: Apply to ISR context
Since ISRs can change variables asynchronously, the compiler must always read the variable fresh, not use cached values.Final Answer:
To tell the compiler the variable can change unexpectedly and prevent optimization errors. -> Option BQuick Check:
Volatile prevents optimization errors in ISR variables = C [OK]
- Thinking volatile makes variable constant
- Assuming volatile allocates more memory
- Believing volatile speeds up code
flag that is modified inside an ISR?Solution
Step 1: Identify the need for volatile
Sinceflagis changed inside an ISR, it must be declaredvolatileto prevent compiler optimizations.Step 2: Check declaration syntax
The correct syntax isvolatile int flag;which tells the compiler to always read the variable fresh.Final Answer:
volatile int flag; -> Option CQuick Check:
ISR-modified variable needs volatile keyword = A [OK]
- Forgetting volatile keyword
- Using const which prevents changes
- Using static without volatile
volatile int flag = 0;
void ISR() {
flag = 1;
}
int main() {
while(flag == 0) {
// wait for flag to change
}
return 0;
}
What will happen if flag was NOT declared volatile?Solution
Step 1: Understand compiler optimization without volatile
Withoutvolatile, the compiler may assumeflagdoes not change in the loop and cache its value.Step 2: Effect on the loop
The loop conditionflag == 0may never be rechecked from memory, causing an infinite loop.Final Answer:
The program may loop forever because the compiler caches flag value. -> Option DQuick Check:
Missing volatile causes infinite loop due to caching = B [OK]
- Thinking program crashes without volatile
- Assuming compile error occurs
- Believing loop exits immediately
int flag = 0;
void ISR() {
flag = 1;
}
int main() {
while(flag == 0) {
// wait
}
return 0;
}Solution
Step 1: Identify variable shared with ISR
The variableflagis modified inside the ISR and read in main.Step 2: Check declaration for optimization safety
Sinceflagis shared, it must be declaredvolatileto prevent the compiler from caching its value.Final Answer:
flag should be declared volatile to avoid optimization issues. -> Option AQuick Check:
Shared ISR variable needs volatile keyword = D [OK]
- Thinking ISR must return a value
- Declaring shared variable const
- Removing the loop instead of fixing volatile
counter incremented inside an ISR and read in the main loop. Which of these is the best way to safely read counter in main without race conditions?Solution
Step 1: Understand volatile role
Declaringcountervolatile ensures main reads fresh value, but does not prevent partial updates during read.Step 2: Prevent race conditions
Disabling interrupts briefly while readingcounterprevents ISR from changing it mid-read, avoiding inconsistent values.Final Answer:
Declare volatile int counter and disable interrupts briefly while reading it in main. -> Option AQuick Check:
Volatile + interrupt disable ensures safe multi-byte read = A [OK]
- Assuming volatile alone prevents race conditions
- Not disabling interrupts during read
- Using const which prevents changes
Ready to prove it?
Pass the test and this pattern moves unknown
