3 Gordon Drive, P.O.Box 1347 Rockland, Maine 04841 U.S.A.
Find Tools for Your Chip


Subscribe to our Newsletter

© 2004 Avocet Systems, Inc.
Call Us Today at 207-596-0080
Avocet Systems, Inc. : The Complete Solution for Embedded Systems Development Tools
Tech Tips
Interrupts: Handle with Care

As you know, interrupt routines almost always have to interact with your background loop. Problems with this interaction can be the hardest bugs to locate in embedded development projects. Here are three quick steps to making your interrupt code more solid.

First, global data that interrupts can change should always be declared as volatile such as:

     volatile char flag;

In this case, leaving out the keyword volatile will lock you right up. The background loop is waiting for an interrupt to change the value of flag:

     while(!flag);

The problem is that this may optimize to:

     if (flag) HALT

With the volatile keyword added to the declaration, even optimized code will re-read the value of flag each time through the while loop.

Secondly, never call the same routine from an interrupt that is called from the background. If a shared routine uses global or static variables, the interrupt can overwrite critical parts in the middle of a background operation. For example, if both background and the interrupt call a function that copies data into a global buffer--and then print it, the background call may be ready to print when the interrupt version kicks in, overwrites the buffer, and prints. This will cause the buffer to print the interrupt version twice, and the background version not at all. Worse, if it's in the middle of a copy, a null terminator could be overwritten and BANG. If you must share functions to save space, make sure those functions are 100% re-entrant.

Finally, whenever an interrupt must access the same data as the background loop, use caution. One example of safe code is as follows. The interrupt routine is:

if (timer !=0) timer --;

For the background loop:

if (timer == 0) timer = DELAY_TIME;

In this example the interrupt can only change the timer if the value is non-zero and the background can only change it if the value is zero. Note that in the worst case, where the interrupt occurs after the value of timer has been checked, it will catch the interrupt properly on the next trip through the background loop. This technique can be used (with care) with longer buffers by using a flag to determine current ownership of the buffer.

These are only a few of the many challenges of interrupt writing. Keep an eye out for future editions of the Avocet Update for more hints about interrupt timing problems in embedded projects.