avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] volatile...


From: David Brown
Subject: Re: [avr-gcc-list] volatile...
Date: Fri, 15 Dec 2006 11:20:56 +0100
User-agent: Thunderbird 1.5.0.8 (Windows/20061025)

address@hidden wrote:
Hello Javier,

Javier Almansa Sobrino wrote:
 > Hi everybody. I've a little stupid question....
> > What's the differece between a volatile variable in a funcion and the same variable not volatile? > > I've noted a non volatile variable is like don't exists (I think). > Despite what some have said about this question, I don't think it is "stupid" as it pertains AVR-GCC (and other microcontroller compilers).

The way I look at it is:
---If you want a GLOBAL to be changed in BOTH real-time-interrupts AND in the foreground, you should use VOLATILE (so that the compiler knows this variable is capable of changing at any time and dependent code is not optimized out of existence).

---If you want a GLOBAL to be changed in EITHER real-time-interrupts OR in the foreground, you don't have to use VOLATILE (but it doesn't hurt).

Regards,
 - Mike Ware



Mike, I'm afraid your understanding of volatile is not correct. You are missing a number of points (Larry, Eric and Graham's posts together cover most of it). And you are wrong about volatile not hurting - unnecessary volatile hurts performance.

The concept of "volatile" is quite simple, and once you understand what it really means, it is clear when it should be used, when it is unnecessary, and when it is not enough for what you want. If you make a variable "volatile" (or access data via a volatile pointer), you are telling the compiler that this memory location may be read from or written to by something other than the C code the compiler is working on.

Forget ideas about "disabling optimisations" - that just gives the impression that some code works best without optimisations, and it is not accurate (some optimisations work perfectly well with volatile data). But if your code asks for a volatile variable to be read, then you know it will be read, rather than re-using old values, and when your code asks for it to be written, then it will be written there and then, and not kept until later.

A common error is thinking that "volatile" is enough to make data safely shareable between interrupt routines and the main program. It does not, as noted by another poster. It is fine for single-byte data used only for simple access, i.e., reads or writes - no attempts at consistent read-modify-writes. (On different architectures, different rules apply - a 16-bit processor can atomically update a 16-bit value, and some processors can safely do read-write-modifies atomically.) For anything else, you need some sort of locking or synchronisation mechanism. Two common ways are to disable interrupts, and to use an atomic byte-sized flag.

The second most common use of "volatile" is for accessing hardware registers. You almost always want these to be volatile, as they are not under full control of the compiler. Use the standard header files, and you won't go wrong.

Another common use is for delay loops.  The old favourite,

    for (int i = 0; i < 1000; i++) ;

does not work - any good compiler will see it as a waste of time, and remove it. There are many other ways of delaying, including some library functions and using the hardware timers, but an easy way is:

    for (volatile int i = 0; i < 1000; i++);

Finally, another great use of volatile is for debugging. If you are having trouble debugging code because your variables are optimised away and the compiler has re-organised the generated code (for efficiency) leaving you struggling for breakpoint locations, then "volatile" can be the answer. If a variable is declared volatile, it will be a real, viewable and modifiable debugger variable. If you make a volatile variable "debugger", then any lines such as "debugger = 1;" (with different values each time) will give you specific code to use for breakpoints. And for advanced users, volatile variables can be used for gdb scripts to communicate with the program.

But always remember that "volatile" cripples the compiler - don't use it unless you really mean it.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]