While reading I came across this type of declaration and the following line -
const volatile char *p=(const volatile char *) 0x30;
We can use the article Introduction to the volatile keyword which says:
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
- Memory-mapped peripheral registers
- Global variables modified by an interrupt service routine
- Global variables within a multi-threaded application
and:
Embedded systems contain real hardware, usually with sophisticated peripherals. These peripherals contain registers whose values may change asynchronously to the program flow. As a very simple example, consider an 8-bit status register at address 0x1234. It is required that you poll the status register until it becomes non-zero. The nave and incorrect implementation is as follows:
UINT1 * ptr = (UINT1 *) 0x1234; // Wait for register to become non-zero. while (*ptr == 0); // Do something else.
This will almost certainly fail as soon as you turn the optimizer on, since the compiler will generate assembly language that looks something like this:
mov ptr, #0x1234 mov a, @ptr loop bz loop
The const says your program won't change the variable but as noted in the article outside sources could and volatile prevents it being optimized away.