[Top][All Lists]

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

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

From: Roger Furer
Subject: Re: [avr-gcc-list] volatile...
Date: Thu, 14 Dec 2006 12:39:54 -1000
User-agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.4) Gecko/20030529

Eric Weddington wrote:

-----Original Message-----
From: address@hidden [mailto:address@hidden
org] On Behalf Of Larry Barello
Sent: Thursday, December 14, 2006 7:43 AM
To: address@hidden; address@hidden
Subject: RE: [avr-gcc-list] volatile...

This is somewhat a compiler issue since it is both a necessary keyword, yet
insufficient to write correct code.  It is a problem that vexes many
newcomers (and old farts like me who forget every now and then) and is
discussed in the FAQ, but is worth burning space here as well.

The GCC compiler is very smart. Global or local (e.g. static) variables are stuffed into SRAM. In a function the compiler will often read the variable into registers and work on it there, stuffing it back out to SRAM later on. Depending upon the routine, e.g. a forever() loop in main(), it may *never*
write it back.

This model, although very efficient, breaks if you have an interrupt handler asynchronously modifying the same variable while it is in registers in the

The "volatile" keyword tells the compiler that *every* access to the
variable has to be done in place, no caching or optimization. A related, but very important, is protecting the operation on the variable with cli/sei instructions. Access and operations typically take multiple instructions. e.g. foo++; Takes three or more instructions. If the interrupt handler
interrupts between the read & write, well, bad things happen.  So, in
reality not only do you have to say "volatile" you must also protect
operations with the cli/sei instruction.

This is an explanation. There is one other area that explains the keyword
"volatile" and that is in register definitions. It is true what Larry said
that "The 'volatile' keyword tellst the compiler that *every* access to the
variable has to be done in place, no caching or optimization." Another way
of saying this is that the variable can be accessed (i.e. written to) by an
entity outside the mainline code. There are mainly two areas where this can
- A variable shared between mainline code and an ISR. This is the situation
described by Larry above.
- And a memory location that can be updated by hardware (i.e. outside the
mainline code). If you take a look at avr-libc, in the macros that define
all the registers, you will see that a register is defined as a number
(address) typecast as a pointer to a *volatile* uint8_t (or uint16_t for 2
byte registers). This is very important as many of these memory-mapped
registers  can be written by the hardware in addition to the mainline code.
This scenario is similar to the mainline/ISR scenario above.

Eric Weddington

AVR-GCC-list mailing list

Given the above, I don't think the question was at all stupid. I certainly appreciate the information. Before this, I knew that "volatile" was used to keep the compiler from optimizing the variable away. But not why and in what cases.
Thank You All,

reply via email to

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