Wednesday, 7 April 2010

Windows CE: Shared interrupt considerations

Hi all,

imagine the following scenario: you have one shared hardware interrupt for multiple devices (i.e. a PCI bus with multiple clients). Typically you would use the supplied giisr.dll as an installable interrupt service routine for your shared interrupt. But what exactly does the giisr do (or rather NOT do), and are there any problems as a result of the giisr behavior?

Upon initialization the giisr adds the interrupt source to a FIFO array, thus the first registered interrupt source has the highest priority.

The interrupt service routine (ISR) simply iterates through the FIFO array and returns the first SYSINTR within the FIFO array or SYSINR_CHAIN if none of the installed devices raised an interrupt. The SYSINTR then triggers the corresponding interrupt service thread (IST)(Given it wasn't SYSINTR_CHAIN).

So far so good, this seems like a regular interrupt handling. So is there any problem with the behavior of the giisr?

Well there is, as you might have noticed the giisr does not do any masking of any subinterrupt. Instead the main (shared) interrupt is masked in the calling ISR. The problem that arises here is that the interrupt latency increases significantly for any device using our shared interrupt. Since instead of unmasking the shared interrupt upon return of the correct SYSINTR, the shared interrupt will stay masked until the corresponding IST has finished and thus blocking any other interrupt raised from a device using the shared interrupt.

The good news is, that you can modify the giisr code in the following way to reduce the interrupt latency to a nearly “normal” level:
  1. 1. Mask the corresponding subinterrupt in the giisr

  2. 2. Unmask the shared interrupt

  3. 3. return the corresponding SYSINTR

  4. 4. in the corresponding IST make sure that InterruptDone does nothing as the shared interrupt is already unmasked, instead unmask the corresponding subinterrupt. NOTE: InterruptDone needs to be called nevertheless to ensure correct interrupt handling

This way other devices using our shared interrupt can be serviced during the processing of an interrupt raised by a different device using the same shared interrupt as it should be. The priority no longer depends on who registers first with the giisr but depends upon the threadpriority of the corresponding IST.

Have fun!

1 comment:

Unknown said...

Could you post giisr.c code to show us what you done at "ISRHandler" to mask and unmask?

Thanks
Lu