Processors with Multiple Interrupt Priorities

There are some processors that actually supports multiple interrupt levels as shown in Figure 9-2.

Figure - Kernel Aware and Non-Kernel Aware Interrupts

(1) Here, we are assuming that the processor supports 16 different interrupt priority levels. Priority 0 is the lowest priority while 15 is the highest. As shown, interrupts are always higher in priority than tasks (assuming interrupts are enabled).

(2) The designer of the product decided that interrupt levels 0 through 12 will be allowed to make µC/OS-III ‘post’ calls to notify tasks that are assigned to service these interrupts. It’s important to note that disabling interrupts (when entering critical sections) for task aware interrupts means raising the interrupt mask to level 12 (this is configured in µC/CPU with the CPU_CFG_KA_IPL_BOUNDARY configuration constant). In other words, interrupt levels 0 through 11 would be disabled but, levels 12 and above would be allowed.

(3) ISRs at interrupt levels 12 through 15 will not be allowed to make any µC/OS-III function calls and are thus implemented as shown in Listing 9-2. It’s important to note that since µC/OS-III cannot disable these interrupts, interrupt latency for these interrupts is very short.


Listing 9-3 shows how to implement non-kernel aware ISRs when the processor supports multiple interrupt priorities.


Listing - Non-Kernel Aware ISRs for Processors with Multiple Priority Levels
          MyNonKernelAwareISR:                                             (1) 
              Save enough registers as needed by the ISR;                  (2) 
              Clear interrupting device;                                   (3) 
              Enable higher priority interrupts (optional);                (4) 
              Call user ISR;                                               (5) 
              Restore the saved CPU registers;                             (6) 
              Return from interrupt;                                       (7) 

(1) As mentioned above, an ISR is typically written in assembly language. MyNonKernelAwareISR corresponds to the name of the handler that will handle the interrupting device.

(2) Here, you save sufficient registers as required to handle the ISR.

(3) The user probably needs to clear the interrupting device to prevent it from generating the same interrupt once the ISR returns.

(4) At this point, you could enable ‘higher priority’ interrupts assuming that the CPU disables all interrupts when the interrupt is accepted. However, you don’t want to enable kernel aware or lower priority interrupts.

(5) Now you can take care of the interrupting device in assembly language or call a C function, if necessary.

(6) Once finished, simply restore the saved CPU registers.

(7) Perform a return from interrupt to resume the interrupted task.