Page 82 - The Art of Designing Embedded Systems
P. 82
Real Time Means Right Now! 69
terrupt rate is such that the routine will return more often than it is invoked.
Again, use the stress test!
Avoid NMI
Reserve NMI-the non-maskable interrupt-for a catastrophe such
as the apocalypse. Power-fail, system shutdown, and imminent disaster are
all good things to monitor with NMI. Timer or UART interrupts are not.
When I see an embedded system with the timer tied to NMI, I know.
for sure, that the developers found themselves missing interrupts. NMI
may alleviate the symptoms, but only masks deeper problems in the code
that must be cured.
NMI will break even well-coded interrupt handlers, since most ISRs
are non-reentrant during the first few lines of code where the hardware is
serviced. NMI will thwart your stack-management efforts as well.
If you’re using NMI, watch out for electrical noise! NMI is usually
an edge-triggered signal. Any bit of noise or glitching will cause perhaps
hundreds of interrupts. Since it cannot be masked, you’ll almost certainly
cause a reentrancy problem. I make it a practice to always properly termi-
nate the CPU’s NMI input via an appropriate resistor network.
NMI mixes poorly with most tools. Debugging any ISR-NMI or
otherwise-is exasperating at best. Few tools do well with single stepping
and setting breakpoints inside of the ISR.
Breakpoint Problems
Using any sort of debugging tool, suppose you set a breakpoint where
the ISR starts, and then start single stepping through the code. All is well.
since by definition interrupts are off when the routine starts. Soon, though,
you’ll step over an E1 instruction or its like. Suddenly, all hell breaks lose.
A regularly occurring interrupt such as a timer tick comes along
steadily, perhaps dozens or hundreds of times per second. Debugging at
human speeds means the ISR will start over while you’re working on a
previous instantiation. Pressing the “single step” button might make the
ISR start, but then itself be interrupted and restarted, with the final stop due
to your high-level debug command coming from this second incarnation.
Oddly, the code seems to execute backwards. Consider the case of
setting two breakpoints-the first at the start of the ISR and the second
much later into the routine. Run to the first breakpoint, stop, and then re-
sume execution. The code may very well stop at the same point, the same
first breakpoint, without ever going to the second. Again, this is simply due

