| Monolithic ISRs | Signals | Task chains | Comments | |
| Non-nested | Yes | Yes | No: User tasks interruptable | Better not be very much to do.
Test interrupt sources in order of priority. |
| Nested | Not usually | No. Trying to do minimal work | Yes: prioritized within task structure | Not very useful without priorities elsewhere
Interrupts block-structured |
| Prioritized Nested | When there is too much to do. | No. Trying to do minimal work | Interruptable kernel, OR free with prioritized tasks | Hard to get right
Do only higher priority nested |
| Prioritized: software | No | No | Yes | Minimal interruption for lower priority |
| Prioritized: hardware | Yes, if processing is long | Yes, for simultaneous interrupts | Yes, for simultaneous interrupts | No interruption for lower priority |
| Vectored, with priority | Yes, for speed | Yes, for speed | Not usually worth it | This cuts out polling of the interrupt controller and the devices. |
Two controllers, daisy-chained
Registers at
47 registers per controller
Priority
What do you do when there are no tasks to run?
HALT
// Initialize hardware
// Find the receiver of the data
FOREVER {
result = AwaitEvent( myevt ); // implicitly turns on interrupts
// interrupts off again on return
switch ( notifier-design ) {
case ALL_IN_KERNEL:
data = result;
break;
case NON_INTERRUPTABLE_NOTIFIER:
data = read-device( );
write-device( ); // to clear present interrupt
write-ICU( ); // to clear current interrupt
}
switch ( task-structure ) {
case DIRECT_SEND:
Send( server, data, ... ); // implicitly turns on interrupts
break; // interrupts off again on return
case COURIER:
Receive( &courier, ... ); // implicitly turns on interrupts
// interrupts off again on return
Reply( courier, data );
break;
case WAREHOUSE:
Send( server, data, ... ); // implicitly turns on interrupts
break; // interrupts off again on return
}
}
// Find notifier and server
FOREVER {
Send (notifier, ..., ..., data, ... );
Send (server, data, ... );
}
// Initialize queues
FOREVER {
Receive( &requester, request, ... );
switch ( request.type ) {
case SERVER:
if ( empty( dataQ ) ) Reply( requester, dequeue( data ), ... );
else enqueue( reqQ, requester );
break;
case NOTIFIER:
enqueue( dataQ, data );
Reply( requester, ... )
while ( !empty( reqQ ) ) Reply( dequeue( reqQ ), dequeue( dataQ ), ... );
}
}
Would like to do
ldr pc, <Vector address register>
as the first instruction of interrupt.
Return to: