Application of volatile in C
A variable should be declared volatile when its value could be changed unexpectedly. In practice, you must declare a variable as volatile whenever you are:
- Accessing the memory-mapped peripherals register.
- Sharing the global variables or buffers between the multiple threads.
- Accessing the global variables in an interrupt routine or signal handler.
Interrupt service routine (ISR)
In the case of Interrupt service routine for a key press interrupt, often a global variable is shared between ISR and main function. In this scenario value of global variable set or check by either the ISR or main function, for example, I am taking a sample code.
void KeyDataISR(void) { keyFlag = 1; } int key_task(void) { while (!keyFlag) { //copy key data via I2C to some variable then reset this flag. } return 0; }
In the above code, the global flag is the monitor in the key_task function, When we have turned on the optimization level of the compiler then might be this code work fine because the compiler is unaware of the value changed of the global variable in ISR, so it assumes that while loop is always true and it never exits from the loop.
A solution of this problem is to make the global keyFlag volatile, this technique prevents the compiler from applying any optimization on the global flag and tells the compiler that value of this flag can change by external event at any time without any action being taken the by code.
volatile int keyFlag = 0; KeyDataISR(void) { keyFlag = 1; } int key_task(void) { while (!keyFlag) { //copy key data via I2C to some variable then reset this flag.
} return 0; }
Application of volatile and const keywords in C
To read the status of the register, address of the register is 0x00020000. To access the value of the status register, we need to map the address of register with a pointer.