Volatile and the GNU C Compiler

Twice now, I’ve been burned.  I’m using the GNU C Compiler with the AVR ATMEGA164PA for my current project, the 8 Bit Synth.  I need to use external interrupts to determine when a switch has been pressed.  When it has, the i/o expander drops its interrupt pin from high to low.  So, I set up the external interrupt routine to be falling edge-triggered.  I had to figure out how to get the i/o expander to trigger its pin when a button was pressed.  I knew that the i/o expander’s output interrupt pin was changing when I pressed a button.  I also knew that the microcontroller’s interrupt service routine was being triggered because I made a pin toggle when the routine ran.  I set a flag high in the service routine.  I configured an if statement in the main routine checking for the flag.  If the flag is set, I need to read the i/o expander’s interrupt latch register to determine which switch was pressed.  The microcontroller never sends the read command.  Not ever, ever.  I couldn’t figure out why.  Do you know?  Follow the jump for the answer to this riddle…

The answer is the C keyword “volatile”.  The global flag that I declared to be set in the interrupt service routine and to be checked in the main routine was not declared with the key word “volatile”.  This key word tells the compiler that the variable can be changed and that it must check its value always.  Without this keyword, the compiler may optimize the code, not seeing any local modification of the variable, and just skip the if statement altogether.  This is exactly what it was doing.

The worst part about it is that I went through this exact same problem six months ago.  To be safe, global variables should always be declared volatile.  This will increase code portability and ensure that you won’t have to deal with this problem.  The Cosmic C compiler for ST microcontrollers does not suffer this problem.  I use it at work all the time, nor do some other compilers that I’ve worked with.  Still, you should incorporate “volatile” as part of your standard operations with global variables.

Posted in General Electronics, Rockit and tagged , , , , , , , .

Leave a Reply