embedded software boot camp

Coding Standard Rule #4: Use volatile Whenever Possible

Friday, March 27th, 2009 by Michael Barr

This is the fourth in a continuing series of blog posts describing simple coding rules that help keep bugs out of embedded C programs.

Rule: The volatile keyword shall be used whenever appropriate, including:

  • 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 tasks, and
  • To declare a pointer to a memory-mapped I/O peripheral register set (e.g., timer_t volatile * const p_timer ).

Reasoning: Proper use of volatile eliminates a whole class of difficult-to-detect bugs by preventing the compiler from making optimizations that would eliminate requested reads or writes to variables or registers that may be changed at any time by a parallel-running entity.

Anecdotal evidence suggests that programmers unfamiliar with the volatile keyword think their compiler’s optimization feature is more broken than helpful and disable optimization. The authors suspect, based on experience consulting with numerous companies, that the vast majority of embedded systems contain bugs waiting to happen due to a shortage of volatile keywords. These kinds of bugs often exhibit themselves as “glitches” or only after changes are made to a “proven” code base.

Coding Standard Rule #3
Coding Standard Rule #5

These rules are excerpts from the Embedded C Coding Standard book.

Tags: , , ,

6 Responses to “Coding Standard Rule #4: Use volatile Whenever Possible”

  1. Erik Shreve says:

    Michael,The following paper/website has some additional information about bugs surrounding the use of volatile:http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdfhttp://www.cs.utah.edu/~eeide/emsoft08/I've recently heard (via a mailing list) that the authors have found several other compilers, beyond those in the paper, with the same issues.One of the takeaways from the paper is a decrease in error rate when volatile access is hidden behind helper function calls.Cheers!Erik Shreve

  2. […] Coding Standard Rule #4: Use volatile Whenever Possible for more on the use of volatile by […]

  3. […] Coding Standard Rule #4: Use volatile Whenever Possible for more on the use of volatile by […]

  4. Luke Teyssier says:

    I agree wholeheartedly with “The volatile keyword shall be used whenever appropriate”. I don’t agree with “Use volatile Whenever Possible”. Volatile comes with a price. In many compilers it will defeat any attempt at optimization, pipelining, or out of order execution around that variable, and possibly for the entire block or function. It’s important to know _exactly_ when volatile is required and use it _every_ time. If volatile is essential to the function of your program, you also need to spot-check the generated assembly at every optimization setting you are using to ensure that your compiler gets it right. Compiler errors here are more common than anyone would like to admit.

    If you suspect a “volatile” problem, many compilers support an option like -fvolatile, which will treat all variables in a module as volatile. This will kill your performance, but at least it can help you track down the problem quickly.

    Further, if you are working on a memory-mapped device, you _must_ ensure cache coherency. This is a major cause of race conditions in device drivers.

    Thanks for the article.

  5. […] such a way that the compiler will never optimize away any of the reads and writes. Though there are several important types of variables to declare volatile, this obscure keyword is especially valuable when you are interacting with hardware peripheral […]

  6. Toby says:

    Some interesting thoughts by Joyhn Regehr at UU on the downsides of volatile (not directly related to the embedded environment though), expecially as regards ordering with respect to other variables.
    http://blog.regehr.org/archives/28

Leave a Reply to Erik Shreve