volatile
Blog Post
Posted Aug 31, 2009
by Colin Walls
Follow on Twitter
Go URL
What is a Go URL?I have often talked and written about my thoughts on programming languages. In particular the fact that there really is no language that was designed with embedded programming specifically in mind. Historically, there was assembly language, but that is rarely used for large scale coding nowadays. Intel promoted PL/M many years ago, but that has fallen by the wayside.
C and C++ are the key languages today. Neither was designed for embedded, but they do the job quite well. Ironically, I think that one of the precursors to C, BCPL, would have been well suited to embedded work, but that language has been consigned to the history books.
There is one feature of C/C++, that is often not well understood, but is a godsend to embedded programmers: the keyword volatile …
When you declare a variable/object volatile, you are telling the compiler not to optimize access to the data. When your code writes a value to the variable, it should be written straight away and not saved in a register for use later. Likewise, when the code reads the value, it should not use a copy that was obtained earlier.
Preparing RecommendationsBroadly speaking, it must be assumed that a volatile variable can change at any time, independently of the current code. This implies two uses: variables that are shared between execution threads [between tasks in an RTOS or between the mainline code and an interrupt service routine]; I/O device registers.
Although volatile is a useful language facility, it is not without difficulties. Firstly, some research has shown that many compilers do not implement the keyword correctly in all circumstances. So care and attention to generated code is required. There are also the usual troubles with C syntax; consider these:
volatile int* pi1 = 0; // pointer to volatile int int* volatile pi2 = 0; // volatile pointer to int volatile int* volatile pi3 = 0; // volatile pointer to volatile int
Plenty of room for errors there! [The same syntactic issues arise with const.]
However, just declaring a variable volatile is not enough if you are sharing it between execution threads [even if there are texts that suggest that this is the case]. To illustrate the problem, consider this code:
volatile x = 1; ... x++;
Syntactically this is fine, but what about the generated code? If the CPU instruction set allows a memory location to be incremented directly with a single, non-interruptible instruction, there is no problem [so long as the compiler uses those instructions!]. But many devices would require the data to be read, incremented and written back. This is all fine according to the language definition, but what if an interrupt occurs during this sequence of instructions?
You need to protect access to it so that the memory location always contains a valid value. You could do this by disabling and re-enabling interrupts or, with an RTOS, maybe a semaphore would be the answer.
[With acknowledgement to my friend Meador Inge, upon whom I can always rely when I get puzzled about compilers, languages etc.]
More Blog Posts
Preparing Recommendations
Comments (↓ Add Your Own)
11 Comments on this Post
Commented on 3:33 PM, Aug 31, 2009
By Dan
Commented on 3:44 PM, Aug 31, 2009
By Colin Walls
Commented on 4:31 PM, Sep 1, 2009
By Russell Klein
Commented on 4:36 PM, Sep 1, 2009
By Colin Walls
Commented on 10:20 AM, Sep 3, 2009
By Michael Barr
Commented on 10:24 AM, Sep 3, 2009
By Colin Walls
Commented on 7:48 AM, Sep 13, 2009
By Sumeet Gupta
Commented on 6:57 PM, Sep 13, 2009
By Colin Walls
Commented on 3:16 AM, Jan 9, 2010
By Kevin Cameron
Commented on 1:46 PM, Jan 11, 2010
By Colin Walls
Commented on 7:42 PM, Jan 17, 2010
By Kevin Cameron
Add Your Comment
Please complete the following information to comment or sign in.