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
   72   73   74   75   76   77   78   79   80   81   82