Page 77 - The Art of Designing Embedded Systems
P. 77
64 THE ART OF DESIGNING EMBEDDED SYSTEMS
If the interrupts are coming fast-a term that is purposely vague and
qualitative, measured by experience and gut feel-then I usually just take
the plunge and code the ISR in assembly. Why cripple the entire system
because of a little bit of interrupt code? If you’ve broken the ISRs into
small chunks, so the real-time part is small, then little assembly will be
needed. Code the slower ISRs in C.
Debugging INT/INTA Cycles
Lots of things can and will go wrong long before your ISR has a
chance to exhibit buggy behavior. Remember that most processors service
an interrupt with the following steps:
1. The device hardware generates the interrupt pulse.
2. The interrupt controller (if any) prioritizes multiple simultaneous
requests and issues a single interrupt to the processor.
3. The CPU responds with an interrupt acknowledge cycle.
4. The controller drops an interrupt vector on the databus.
5. The CPU reads the vector and computes the address of the user-
stored vector in memory. It then fetches this value.
6. The CPU pushes the current context, disables interrupts, and
jumps to the ISR.
Interrupts from internal peripherals (those on the CPU itself) usually
won’t generate an external interrupt acknowledge cycle. The vectoring is
handled internally and invisibly to the wary programmer, tools in hand,
trying to discover his system’s faults.
A generation of structured programming advocates has caused many
of us to completely design the system and write all of the code before de-
bugging. Though this is certainly a nice goal, it’s a mistake for the low-level
drivers in embedded systems. I believe in an early wrestling match with the
system’s hardware. Connect an emulator and exercise the I/O ports. They
never behave quite as you expected. Bits might be inverted or transposed,
or maybe there are a dozen complex configuration registers that need to be
set up. Work with your system, understand its quirks, and develop notes
about how to drive each YO device. Use these notes to write your code.
Similarly, start prototyping your interrupt handlers with a hollow
shell of an ISR. You’ve got to get a lot of things right just to get the ISR to
start. Don’t worry about what the handler should do until you have it at
least being called properly.
Set a breakpoint on the ISR. If your shell ISR never gets called, and
the system doesn’t crash and burn, most likely the interrupt never makes it

