Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Even though an interrupt controller is present in most designs, some CPUs still vector to a common interrupt handler, and the ISR queries the interrupt controller to determine the source of the interrupt. At first glance, this might seem silly since most interrupt controllers are able to force the CPU to jump directly to the proper interrupt handler. It turns out, however, that with µC/OS-III, it’s easy to have the interrupt controller vector to a single ISR handler. Listing 9-4 describes the sequence of events to be performed when the interrupt controller forces the CPU to vector to a single location.

Anchor
Listing - Single interrupt vector for all interrupts
Listing - Single interrupt vector for all interrupts

Code Block
languagecpp
titleListing - Single interrupt vector for all interrupts
linenumberstrue
 An interrupt occurs;                                       (1)
 The CPU vectors to a common location;                      (2)
 The ISR code performs the "ISR prologue"                   (3)
 The C handler performs the following:                      (4)
     while (there are still interrupts to process) {        (5)
         Get vector address from interrupt controller;      
         Call interrupt handler;                            
     }
 The "ISR epilogue" is executed;                            (6)


Panel
bgColor#f0f0f0

(1) An interrupt occurs from any device. The interrupt controller activates the interrupt pin on the CPU. If there are other interrupts that occur after the first one, the interrupt controller will latch them and properly prioritize the interrupts.

(2) The CPU vectors to a single interrupt handler address. In other words, all interrupts are to be handled by this one interrupt handler.

(3) The ISR executes the “ISR prologue” code needed by µC/OS-III. as previously described. This ensures that all ISRs will be able to make µC/OS-III “post” calls.

(4) You call a µC/OS-III C handler, which will continue processing the ISR. This makes the code easier to write (and read). Notice that interrupts are not re-enabled.

(5) The µC/OS-III C handler then interrogates the interrupt controller and asks it: “Who caused the interrupt?” The interrupt controller will either respond with a number (0 to N-1) or with the address of the interrupt handler for the highest priority interrupting device. Of course, the µC/OS-III C handler will know how to handle the specific interrupt controller since the C handler is written specifically for that controller.

If the interrupt controller provides a number between 0 and N-1, the C handler simply uses this number as an index into a table (in ROM or RAM) containing the address of the interrupt service routine associated with the interrupting device. A RAM table is handy to change interrupt handlers at run-time. For many embedded systems, however, the table may also reside in ROM.

If the interrupt controller responds with the address of the interrupt service routine, the C handler only needs to call this function.

In both of the above cases, all interrupt handlers need to be declared as follows:

void MyISRHandler (void);

There is one such handler for each possible interrupt source (obviously, each having a unique name).

The “while” loop terminates when there are no other interrupting devices to service.

(6) The µC/OS-III “ISR epilogue” is executed to see if it is necessary to return to the interrupted task, or switch to a more important one.


A couple of interesting points to note:

...