CS452 - Real-Time Programming - Fall 2009

Lecture 14 - AwaitEvent

Reminders


How OSs Handle Interrupts

  1. ISRs that do all the work
  2. ISRs that work asynchronously
  3. ISRs that trigger other processes

Interrupt Handling Methods

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.

ARM Specific

Two controllers, daisy-chained

Registers at

47 registers per controller

Priority

  1. FIQ-configured interrupts (not vectored)
  2. IRQ-configured vecored interrupts
  3. IRQ-configured non-vectored interrupts

HALT versus an Idle Task

What do you do when there are no tasks to run?

HALT


Task Structure for Notifiers

Notifier

// 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
   }
}

Courier

// Find notifier and server
FOREVER {
   Send (notifier, ..., ..., data, ... );
   Send (server, data, ... );
}

Warehouse

// 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 ), ... );
   }
}

Vectored Interrupts

Registers

  1. Vector Address Register
  2. Address of handler
  3. Control register

Programming

Would like to do

   ldr   pc, <Vector address register>

as the first instruction of interrupt.


Return to: