|
3
Gordon Drive, P.O.Box 1347 Rockland, Maine 04841 U.S.A.
|
|
© 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.
|
|
|