7

I have been recently working on learning embedded systems programming on my own. I have observed a fairly high usage of the keyword volatile qualifier when declaring variables?

What is the significance of volatile when declaring a variable in Embedded System programming?

Basically when the should the key word be used. I did read something about compiler optimization and use of the keyword. Also something related to memory mapping registers.

For example, I read this StackOverflow post but I didn't understand how it applied in an embedded environment. More specifically, I don't understand when the key word should be used. I did read something about compiler optimization and use of the keyword. Also something related to memory mapping registers, but I don't understand when to use it.

Community
  • 1
  • 1
706Astor
  • 285
  • 2
  • 10

5 Answers5

10

Let's have a look at an example. When you look at C header files for PIC microcontrollers, you will see that many elements are declared volatile:

extern volatile unsigned char           PORTB               @ 0x006;

As you have read, the volatile keyword disables compiler optimization. Suppose you write a program that does the following:

PORTB = 0x00;            // set all of port B low
while (PORTB == 0x00);   // wait for any pin to get high
// do something else

When the compiler optimises this code, it will recognise the second line as an infinite loop: the condition is true and never gets false within its body. Therefore, everything after the infinite loop does not need to be compiled as it will never be ran. Hence, the compiler may decide to not include that part of the code in the generated assembly code.

However, this PORTB is actually linked to a physical port. It is a hardware port whose value may be altered by the external circuitry. This means that although the loop seems to be infinite, it doesn't have to be. The compiler can't possibly know this.

That's where volatile comes in. When PORTB is declared volatile, the compiler won't do any optimisation based on reasoning about PORTB. It will assume that its value may be changed at any time by external factors.

6

In the embedded systems world, one of the key aspects of the volatile key-word is that it denotes a variable that may change at any time (eg an external/hardware data input - eg an ADC) and therefore the compiler must not optimise use.

But specifically, when used with a control register, it indicates that a read access may in fact change the data!

As a general rule of thumb, I would recommend the use of the volatile qualifier in all of the following:

  • All hardware register accesses(read and write)
  • All variables that are accessible in multiple threads (especially interrupt handlers)

Note: accessing a volatile is not necessarily atomic, so it is imperative that you know your hardware and your code structure.

2

The volatile keyword is primarily used tell the compiler the value of the variable may change anytime. It also tells the compiler the not to apply optimization on the variable. I am not too much of an expert on this but below is good reference that I have referred in the past.

volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time-without any action being taken by the code the compiler finds nearby. The implications of this are quite serious. However, before we examine them, let's take a look at the syntax.

Reference:

Mahendra Gunawardena
  • 1,956
  • 5
  • 26
  • 45
1

Let me put it in other perspective it is exactly opposite of const keyword. When compiler encounters const qualifier for any variable it checks if any function or statement is modified it once initialized. Hence flag error.

Volatile is exactly opposite, this variable can be changed by any function. Hence compiler does not apply optimization.

You see this mostly in embedded system programming due to use of interrupts and some programming logic constructs seems redundant.

  • 3
    Thist is inaccurate. It can be changed by factors *external to the program you're writing*. Variables that can be changed by any function are called global scope variables, which is orthogonal to whether they're declared as `volatile`. –  Aug 08 '15 at 08:05
0

While the statements about optimization are correct, they seem a little unclear to me. Here is what is really going on.

If you don't use the volatile keyword C may optimize that variable into a register it isn't using at the time. This will make for fewer assembly instructions and the code will execute faster.

For example, consider the following...

extern int my_port;    // my_port is defined in a different module somewhere
                       // presumably a memory mapped hardware port
while (my_port > 0) {so stuff}

The compiler may decide to read my_port into a register only once before the actual while statement, then each time to test my_port it will look at the register not the memory location.

If, however, my_port is a hardware port, the port may change but register won't and the while conditional will not change.

The loop variable (the register) will be "out of phase" with the actual variable (my_port).

Thus the need for the keyword volatile.

Volatile tells C, "Don't optimize this variable into a reg, but read it each and every time you need it."

More instructions are generated, code is a bit slower, but it is always accurate.

Cool Javelin
  • 776
  • 2
  • 10
  • 26