RTEMS Logo

RTEMS 4.6.99.3 On-Line Library


Interrupts Interrupt Dispatching

PREV UP NEXT Bookshelf RTEMS Porting Guide

5.5.2: Interrupt Dispatching

The _ISR_Handler routine provides the RTEMS interrupt management.

void _ISR_Handler()

This discussion ignores a lot of the ugly details in a real implementation such as saving enough registers/state to be able to do something real. Keep in mind that the goal is to invoke a user's ISR handler which is written in C. That ISR handler uses a known set of registers thus allowing the ISR to preserve only those that would normally be corrupted by a subroutine call.

Also note that the exact order is to a large extent flexible. Hardware will dictate a sequence for a certain subset of _ISR_Handler while requirements for setting the RTEMS state variables that indicate the interrupt nest level (_ISR_Nest_level) and dispatching disable level (_Thread_Dispatch_disable_level) will also restrict the allowable order.

Upon entry to _ISR_Handler, _Thread_Dispatch_disable_level is zero if the interrupt occurred while outside an RTEMS service call. Conversely, it will be non-zero if interrupting an RTEMS service call. Thus, _Thread_Dispatch_disable_level will always be greater than or equal to _ISR_Nest_level and not strictly equal.

Upon entry to the "common" _ISR_Handler, the vector number must be available. On some CPUs the hardware puts either the vector number or the offset into the vector table for this ISR in a known place. If the hardware does not provide this information, then the assembly portion of RTEMS for this port will contain a set of distinct interrupt entry points which somehow place the vector number in a known place (which is safe if another interrupt nests this one) and branches to _ISR_Handler.

save some or all context on stack
may need to save some special interrupt information for exit

#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
    if ( _ISR_Nest_level == 0 )
        switch to software interrupt stack
#endif
_ISR_Nest_level++;
_Thread_Dispatch_disable_level++;
(*_ISR_Vector_table[ vector ])( vector );
--_ISR_Nest_level;
if ( _ISR_Nest_level )
    goto the label "exit interrupt (simple case)"
#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
    restore stack
#endif

if ( _Thread_Dispatch_disable_level )
   _ISR_Signals_to_thread_executing = FALSE;
    goto the label "exit interrupt (simple case)"

if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing )
   _ISR_Signals_to_thread_executing = FALSE;
   call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
   prepare to get out of interrupt
   return from interrupt  (maybe to _ISR_Dispatch)

LABEL "exit interrupt (simple case):
 prepare to get out of interrupt
 return from interrupt

Some ports have the special routine _ISR_Dispatch because the CPU has a special "interrupt mode" and RTEMS must switch back to the task stack and/or non-interrupt mode before invoking _Thread_Dispatch. For example, consider the MC68020 where upon return from the outermost interrupt, the CPU must switch from the interrupt stack to the master stack before invoking _Thread_Dispatch. _ISR_Dispatch is the special port specific wrapper for _Thread_Dispatch used in this case.


PREV UP NEXT Bookshelf RTEMS Porting Guide

Copyright © 1988-2004 OAR Corporation