Volatile Type Qualifier
Today, I learned about the volatile keyword. This keyword is particularly useful when working with memory-mapped hardware devices. It indicates to the compiler that the value of a variable may change at any time, often due to factors external to the programās normal flow of control, such as the use of semaphores, mutexes, or threads. By using the volatile keyword, you ensure that accesses to such variables are not optimized away by the compiler, as it recognizes that the variableās value could be altered asynchronously. This is crucial, especially when dealing with device registers or shared variables in concurrent programming scenarios.
Some examples where the volatile keyword should be used:
To declare a global variable accessible (by current use or scope) by any interrupt service routine.
To declare a global variable accessible (by current use or scope) by two or more threads.
To declare a pointer to a memory-mapped I/O peripheral register set
To declare a delay loop counter.
Here is how we could declare a volatile semaphore in C based on my previous article:
An interesting anecdote from the book āEmbedded C Coding Standardā where I first learned about volatile:
Anecdotal evidence suggests that programmers unfamiliar with the volatile keyword believe their compilerās optimization feature is more broken than helpful and disable optimization. We believe that the vast majority of embedded systems contain bugs waiting to happen due to missing volatile keywords. Such bugs typically manifest themselves as āglitchesā or only after changes are made to a āprovenā code base.
Here is a good example from the documentation (link below) to see how the volatile keyword can be used and how it affects optimization. Try it yourself and see how the time differs:
Here is the documentation for the volatile type qualifier.
Last updated