Volatile Keyword in Embedded System

Volatile Variable in C language

Citation
, XML
Authors

Volatile variable – C Language

Context : C Language

Rasmi Ranjan Nayak


Hello Friends,

I think, you might have heard of Volatile keyword in programming languages. But, when it comes to writing code especially in Embedded programming the use of “volatile” keyword is very often.

But now the question is,

  • What is it (volatile)?

  • What it does?

  • Why do we need it?

  • Does my program/code really need this keyword?

All these and more I will cover in this article.

What does volatile mean?

Ok, let’s find out the meaning of volatile in dictionary.

VOLATILE means: – UNSTABLE, UNPREDICTABLE…etc.

So, the basic meaning of volatile is we can’t predict what is going to happen next.

Now,

What is the significance of volatile keyword?

The significance of volatile keyword in programming language is to inform/tell the compiler not to pre-predict/assume/believe/presume the value of the particular variable which has been declared as volatile.

What is code optimization?

I think this is the particular section is missing everywhere. So now we will see, what is code optimization….

Look at the figure 1 and Figure 2, below.

Suppose:-

Figure 1

int x = 0;

main()

{

if (x == 0) /* This condition is always true */

{

printf(“x = 0 \n”);

}

else /*Else part will be optimized because x will never ever other than 0*/

{

printf(“x != 0 \n”);

}

}

Figure 2

volatile int x; /* volatile Keyword*/

main()

{

x = 0;

if (x == 0)

{

printf(“x = 0 \n”);

}

else

/*Else part will never ever be optimized

because the variable is declared as volatile*/

{

printf(“x != 0 \n”);

}

In fig-1, compiler will optimize the code it will ignore the else part, because the variable “x” will never ever become other than 0.

In fig-2, the compiler will never ever optimized the code (else part) because, by declaring x as volatile compiler comes to know that this variable can change at any point of time. So compiler does not ignore the else part.

Why/When do we need it?

In following case we need to use volatile variable.

  • Memory-mapped peripheral registers

  • Global variables modified by an interrupt service routine

  • Global variables within a multi-threaded application

If we do not use volatile qualifier the following problems may arise:

  • Code that works fine-until you turn optimization on

  • Code that works fine-as long as interrupts are disabled

  • Flaky hardware drivers

  • Tasks that work fine in isolation-yet crash when another task is enabled

e.g

static int var; void test(void) {

var = 1; while (var != 10) continue;

}

The above code sets the value in var to 1. It then starts to poll that value in a loop until the value of var becomes 10.

An optimizing compiler will notice that no other code can possibly change the value stored in ‘var’, and therefore assume that it will remain equal to 0 at all times. The compiler will then replace the function body with an infinite loop,similar to this:

void test_opt(void) {

var = 0; while (TRUE)/*#define TRUE 1*/ continue; }

How do we declare a volatile variable?

Include the keyword volatile before or after the data type in the variable.

volatile int var;

or

int volatile var;

Pointer to a volatile variable

volatile int * var;

int volatile * var;

Above statements implicate ‘var’ is a pointer to a volatile integer.

Volatile pointers to non-volatile variables

int * volatile var; –> Here var is a volatile pointer to a non-volatile variable/object. This type of pointer are very rarely used in embedded programming.

Volatile pointers to volatile variables

int volatile * volatile var;

If we qualify a struct or union with a volatile qualifier, then the entire contents of the struct/union becomes volatile. We can also apply the volatile qualifier to the individual members of the struct/union.

Does my program/code really need this keyword?

As we have already seen above, when do we need volatile keyword, then below are some cases which really makes you understand.

Usages of volatile qualifier

Peripheral registers

I would like to insist you to visit this below website for better understanding

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3750.html

Most embedded systems consist of a handful of peripherals devices. The value of the registers of these peripheral devices may change asynchronously. Lets say there is an 8-bit status register at address 0×1234 in any hypothetical device. What we need to do is to poll this status register until it becomes non-zero. The following code snippet is an incorrect implementation of this scenario/requirement:

UINT1 * ptr = (UINT1 *) 0×1234;

// Wait for register to become non-zero.

while (*ptr == 0);

// Do something else.

Now no code in proximity attempts to change the value in the register whose address(0×1234) is kept in the ‘ptr’ pointer. A typical optimizing compiler(if optimization is turned ON) will optimize the above code as below:

mov ptr, #0×1234 -> move address 0×1234 to ptr

mov a, @ptr -> move whatever stored at ‘ptr’ to accumulator

loop bz loop -> go into infinite loop

What the assumes while optimizing the code is easy to interpret. It simply takes the value stored at the address location 0×1234(which is stored in ‘ptr’) into accumulator and it never updates this value as because apparently the value at the address 0×1234 never gets changed(by any nearby code). So, as the code suggests, the compiler replaces it with an infinite loop (comparing the initial zero value stored at the address 0×1234 with a constant ‘zero’). As the value stored at this address would initially be zero and it is never updated, this loop goes forever. The code beyond this point would never get executed and the system would go into a hanged state.

So what we essentially need to do here is to force the compiler to update the value stored at the address 0×1234 whenever it does the comparison operation. The volatile qualifier does the trick for us. Look at the code snippet below:

UINT1 volatile * ptr = (UINT1 volatile *) 0×1234;

The assembly for the above code should be:

mov ptr, #0×1234 -> move the address 0×1234 to ptr

loop mov a, @ptr -> move whatever stored @address to accumulator

bz loop -> branch to loop if accumulator is zero

So now at every loop the actual value stored at the address 0×1234(which is stored in the ‘ptr’) is fetched from the peripheral memory and checked whether it’s zero or non-zero; as soon as the code finds the value to be non-zero the loop breaks. And that’s what we wanted.

Subtler problems tend to arise with registers that have special properties. For instance, a lot of peripherals contain registers that are cleared simply by reading them. Extra (or fewer) reads than you are intending can cause quite unexpected results in these cases.

ISR(Interrupt Service Routine)

Sometimes we check a global variable in the main code and the variable is only changed by the interrupt service routine. Lets say a serial port interrupt tests each received character to see if it is an ETX character (presumably signifying the end of a message). If the character is an ETX, the serial port ISR sets a particular variable, say ‘etx_rcvd’. And from the main code somewhere else this ‘etx_rcvd’ is checked in a loop and untill it becomes TRUE the code waits at this loop. Now lets check the code snippet below:

int etx_rcvd = FALSE;

void main()

{

while (!ext_rcvd)

{

// Wait

}

}

interrupt void rx_isr(void)

{

if (ETX == rx_char)

{

etx_rcvd = TRUE;

}

}

This code may work with optimization turned off. But almost all the optimizing compiler would optimize this code

to something which is not intended here. Because the compiler doesn’t even have any hint that etx_rcvd can be

changed outside the code somewhere( as we saw within the serial port ISR). So the compiler assumes the

expression !ext_rcvd would always be true and would replace the code with infinite loop. Consequently the

system would never be able to exit the while loop. All the code after the while loop may even be removed by the

optimizer or never be reached by the program. Some compiler may throw a warning, or some may not, depends

completely on the particular compiler.

The solution is to declare the variable etx_rcvd to be volatile. Then all of your problems (well, some of them

anyway) will disappear.

Multi-threaded applications

Often tasks/threads involved in a multi-threaded application communicate via a shared memory location i.e.

through a global variable. Well, a compiler does not have any idea about preemptive scheduling or to say, context

switching or whatsoever. So this is sort of same problem as we discussed in the case of an interrupt service routine

changing the peripheral memory register. Embedded Systems Programmer has to take care that all shared global

variables in an multi threaded environment be declared volatile. For example:

int cntr;

void task1(void)

{

cntr = 0;

while (cntr == 0)

{

sleep(1);

}

}

void task2(void)

{

cntr++;

sleep(10);

}

This code will likely fail once the compiler’s optimizer is enabled. Declaring ‘cntr’ to be volatile is the proper way to solve the problem.

Some compilers allow you to implicitly declare all variables as volatile. Resist this temptation, since it is essentially a substitute for thought. It also leads to potentially less efficient code.

Can you have constant volatile variable? You can have a constant pointer to a volatile variable but not a constant volatile variable.

Consider the following two blocks of a program, where second block is the same as first but with volatile keyword. Gray text between lines of C code means i386/AMD64 assembler compiled from this code.

{

BOOL flag = TRUE;

while( flag );

repeat:

jmp repeat

}

{

volatile BOOL flag = TRUE;

mov dword ptr [flag], 1

while( flag );

repeat:

mov eax, dword ptr [flag]

test eax, eax

jne repeat

}

In first block variable ‘flag’ could be cached by compiler into a CPU register, because it does not have volatilequalifier. Because no one will change value at a register, program will hang in an infinite loop (yes, all code belowthis block is unreachable code, and compiler such as Microsoft Visual C++ knows about it). Also this loop wasoptimized in equivalent program with the same infinite loop, but without involving variable initialization andfetching. ‘jmp label’ means the same as ‘goto label’ in C code.

Second block have volatile qualifier and have more complex assembler output (initializing ‘flag’ with ‘mov’instruction, in a loop fetching this flag into CPU register ‘eax’ with a ‘mov’ instruction, comparing fetched valuewith zero with ‘test’ instruction, and returning to the beginning of the loop if ‘flag’ was not equal to zero. ‘jne’ means’goto if not equal’). This is all because volatile keyword prohibits compiler to cache variable value into CPUregister, and it is fetched in all loop iterations. Such code is not always is an infinite loop, because another threadin the same program potentially could change value of variable ‘flag’ and first thread will exit the loop.

It is important to understand that volatile keyword is just a directive for compiler and it works only at a compile-time.

For example, the fact of using interlocked operation differs from just a compiler option, since special assembler commands are produced. Thus, interlocked instructions are most like to hardware directives, and they work at a run-time.

Can A Variable be both Volatile and Const?

const means the program can not modify the value

volatile means the value may be arbitrarily modified outside the program.

the two are separate and not mutually exclusive.

use them together, for instance, in the case of reading a hardware status register. const prevents the value from being stomped on, while volatile tells the compiler that this value can be changed at any time external to the program.

This,

const volatile <type> <variablename>

will thus satisfy both requirements and prevent an optimizing compiler from incorrectly optimizing the code, that it would do if only “const” were used.

Conclusion

1. A volatile variable can be changed by the background routine of preprocessor. This background routine may be interrupt signals by microprocessor, threads, real times clocks etc.

2. In simple word we can say a value volatile variable which has stored in the memory can be by any external sources.

3. Whenever compiler encounter any reference of volatile variable is always load the value of variable from memory so that if any external source has modified the value in the memory complier will get its updated value.

4. Working principle of volatile variable is opposite to the register variable in c. Hence volatile variables take more execution time than non-volatile variables.

I hope this article might have helped you in understanding volatile keyword.

Do find my other Articles.

Automotive Diagnostics Services

Automotive Embedded Questions

Stop and Start Mechanism

Reference:

http://www.eetimes.com/discussion/other/4023801/Introduction-to-the-Volatile-Keyword

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3750.html

http://en.wikibooks.org/wiki/Embedded_Systems/C_Programming

http://www.cognitus.net/html/tutorial/usingVolatile.html

http://www.netrino.com/node/80

http://icecube.wisc.edu/~dglo/c_class/const_vol.html

http://www.daniweb.com/software-development/c/threads/187964

24 Comments

Comments RSS
  1. jigar

    wov…i have experience of 2 years in embedded still the concept of Volatile Variable in C language is not clear in my mind….thanks for help….

    • Rasmi Ranjan Nayak

      @Jigar: You are welcome. I am glad that, the article helped you in understanding the concept.

  2. Lawerence Leverance

    My spouse and i still can’t quite feel that I could be one of those reading through the important suggestions found on your site. My family and I are truly thankful for the generosity and for offering me the possibility to pursue my personal chosen profession path. Thanks for the important information I got from your blog.

    • Rasmi Ranjan Nayak

      Lawerence Thanks A Lot from bottom of my heart……… I am glad that, my article did help you.

    • Rasmi Ranjan Nayak

      Lawerence Thanks A Lot from bottom of my heart……… I am glad that, my article did help you.

  3. Erik Bawany

    I’m pleased I found this article. Your information is thought-provoking and most interesting. I agree with the points you have made here in this writing.

  4. Nidhi

    This article is really helpful.i didnt get such a nice description on this Topic.. Thanks a lot..

  5. Abhishek

    How does volatile intialise the memory. Plz any tell me about intialising the memory

    • Rasmi Ranjan Nayak

      Hello Abhishek,
      As far as my knowledge when a variable is declared as volatile (to prevent aggressive compiler optimization) a special memory location is reserved.
      Suppose,
      int a = 0; //Suppose a is stored in location 0×2000
      abc:
      if(a == 0)
      //Do something
      else
      //Do Nothing
      goto abc;
      In above case compiler will check the value only once and makes sure that it will never ever gonna change then else part will be optimized aggressively.
      _____
      Next,

      volatile int a = 0; //Suppose a is stored in location 0×2000
      int b = 0;
      abc:
      if(a == 0)
      //Do something
      b = a * a;
      else
      //Do Nothing
      goto abc;
      Every time compiler will go to location 0×2000 and check what is the value of ‘a’ and then it will proceed. In the above, if the “if-condition” satisfies then when control reaches to the statement
      b = a (/*1st a*/) * a (/*2nd a*/);
      compiler will go to 0×2000 location and will check the the value of a twice.
      Because (1st a != 2nd a) // Might be possible.
      Suppose if 1st a = 0, before executing 2nd a suppose the value of a got changed by some external interrupt.

      I think the above helps you. If anymore question then reply me

  6. ReddyKiran

    Master… your Article on “Volatile” is really good…thank you!! :)

  7. Venkat

    This artical is very helpful for me. thanks alot

  8. Ali

    hi can u plz give me the ans what is the
    use of volatile and static together in coding

    • Rasmi Ranjan Nayak

      Hello Mr. Khan,
      Actually I could not able to understand ur question properly.
      But still I will ans what I understood..
      Why volatile:
      Short Ans:-Where you have don’t have faith of value of a volatile variable. (Read Article once again).
      Why Static:
      Short Ans:- When you want your variable needs to be initialized once then you need static.
      See the example,
      main(){/*Pseudo code*/
      static int x;//x = 0 by default
      printf(“%d\n”, x++);
      main();/*It is a bad coding practice to call main()*/
      /*This example main() is called, only for understanding purpose*/
      }

      You can visit
      http://stackoverflow.com/questions/3509219/does-the-order-of-static-and-volatile-keywords-matter

  9. Tejbir

    Thanx a lot sir very very helpful

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

%d bloggers like this: