NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » recognizing when to use volatile

November 06, 2010
by kle8309
kle8309's Avatar

So I have been looking at the Ps/2 keyboard interface c code from NK. I understand the idea of using volatile. But how do I know in which situation will my compiler will make those assumptions to optimize the code.

In the c code by NK:

volatile uint8_t kbd_data; volatile uint8_t char_waiting; uint8_t started;

Why is only two variable declared as volatile. Aren't we afraid that the compiler will make similar optimization for the variable started too?

Do we only use volatile only if the variable will be used in a while loop argument?

November 07, 2010
by mrobbins
(NerdKits Staff)

mrobbins's Avatar

Hi Kelvin,

The general reason to use "volatile" is when a variable is modified by interrupt code but being read by non-interrupt code.

We haven't really talked about processor registers versus RAM, but basically, during the execution of one function, registers are used to work with information. That means generally, information is copied from RAM to a register, then work is done on it (even something simple like comparing == 0), and it might be saved back to RAM when the function exits.

An interrupt handler is itself a function which will properly write variables back to RAM even if it was temporarily modifying them in registers during the body of the function.

However, the main function never exits, and so never has a reason to re-copy the values from RAM to a register. Therefore, it will never notice that the interrupt handler function changed the variable in RAM. To force it to do so anyway, we mark the variable as "volatile", so the compiler will copy it from RAM to register every time it is referenced in the code. That way, the updates from the interrupt handler in RAM will be propogated to the register and used in the while loop.

In this particular case, "started" doesn't need to be volatile because it's never read from anywhere but the interrupt handler. In contrast, "char_waiting" is read from the main function's while loop, and kbd_data is read from the read_char function. (Even though the kbd_data read is done inside a read_char function, and you might think that based on my earlier description that anything done inside a function like this is safe because the compiler will copy from RAM to register at the start of the function, the truth is that the compiler might try to be efficient and "inline" a simple function like that one.)

(Furthermore, this can all get a bit more complicated with things like reentrant interrupts, where one interrupts can interrupt another, or even itself...)

Hope that helps!


Post a Reply

Please log in to post a reply.

Did you know that our USB NerdKit works on Windows, Linux, and Mac OS X? Learn more...