When to use volatile qualifier?
- A variable must be declared using a volatile qualifier when there is a possibility of unexpected changes in the variable value.
- The unexpected changes in the variable value may happen from within the code or from outside the code or from the hardware.
Use volatile when your code is dealing with below scenarios
- Memory-mapped peripheral registers of the microcontrollers.
- Multiple tasks accessing global variables(read/write) in an RTOS multithreaded application.
- When a global variable is used to share data between the main code and an ISR code.
In all these scenarios use volatile generously. So, for other cases volatile is not required. Especially for these three reasons, you should use volatile.
Syntax of using ‘volatile’
Let’s understand a couple of cases.
Case 1: volatile data
For example, if you have a variable my_data, then you can convert this into volatile data using the volatile keyword, so you can use
uint8_t volatile my_data;
First, mention the type specifier and then mention the volatile keyword and then write the variable name. This is the preferred method or you can also use volatile uint8_t my_data; No problem. Both are identical.
How do you read this?
my_data is a volatile variable of type uint8.
Case 2 : non-volatile pointer to volatile data
This is the case we use most frequently in embedded system programming when we deal with memory-mapped peripheral registers. This is similar to a const.
Here uint8_t volatile is a data and pStatusReg is a pointer. pStatusReg is a non-volatile pointer, pointing to volatile data of type unsigned integer_8.
What is the use case of this?
– This is a perfect case of accessing memory-mapped registers.
– Use this syntax generously whenever you are accessing memory-mapped registers in your microcontroller code.
So, by using uint8_t volatile *pStatusReg; this syntax, basically we are telling the compiler that the data pointed by the pStatusReg pointer is volatile in nature. That means the data may change unexpectedly. That’s why not do any optimization on data read or data write operations using this pStatusReg pointer.
Case 3 and Case 4 are rarely used.
Case 3 : volatile pointer to non-volatile data
Syntax: uint8_t *volatile pStatusReg;
Case 4: volatile pointer to volatile data
Syntax: uint8_t volatile *volatile pStatusReg;
As I said these are rarely used, so we will not be discussing these syntaxes.
And remember that, the keywords ‘const’ and ‘volatile’ can be applied to any declaration, including those of structures, unions, enumerated types, or typedef names.
Get Full Course on Microcontroller Embedded C Programming Here.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1