Embedded Systems Fundamentals · Interview question

Why must a variable shared between an ISR and main code be volatile, and is volatile enough?

A strong answer

volatile is necessary for visibility: without it, the compiler may cache the variable in a register across the main loop and never observe the ISR's update, so a while (!flag) {} wait spins forever on a stale cached value, or the ISR's write gets optimized as dead. volatile forces every access to hit memory, so each side sees the other's writes. But volatile is not sufficient when the access is a read-modify-write or spans multiple bytes/words. shared_count++ compiles to load-increment-store; if the ISR fires between the main code's load and store (or vice versa), one update is lost, a data race that volatile does nothing to prevent, because it guarantees the accesses happen but not that they're atomic. For RMW or multi-word shared data you need a critical section (briefly disable the interrupt around the access) or atomic operations. On a 32-bit Cortex-M, a single aligned 32-bit volatile load or store is atomic, so a simple flag set/clear is fine with volatile alone, but anything compound needs explicit protection. So: volatile for visibility always; critical section/atomics additionally whenever the operation isn't a single atomic access.

What a weak answer sounds like

You know the answer. Do you know what gets you dinged?

Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.

From the lesson

Interrupts & ISRs

Let hardware tap the CPU on the shoulder instead of polling: the NVIC, the vector table, interrupt latency, and the hard rules for writing a correct ISR.

More Interrupts & ISRs questions

Browse all 472 interview questions
Why must a variable shared between an ISR and main code be volatile, and is volatile enough? | EmbeddedPrep.io