INtime SDK Help
SetRtInterruptHandlerEx
INtime SDK v7.1 > About INtime > INtime Kernel > Interrupts > SetRtInterruptHandlerEx

Assigns an interrupt handler to the specified interrupt level, and optionally makes the calling thread the interrupt thread for that level. This call can also designate a handler as a shared handler, or an MSI handler. It is not necessary for the handler to have an associated thread.

Typically the programmer is required to call SetRtInterruptHandlerEx in place of SetRtInterruptHandler in the case of PCI interrupt handlers (because they can be shared) and in the case of MSI handlers.

WORD SetRtInterruptHandlerEx(
  WORD wLevel,
  BYTE byMaxInt,
  LPPROC lpfnHandler,
  LPVOID lpParamPtr
);

Parameters

wLevel
Specifies the interrupt level to which the handler is to be assigned.
byMaxInt
Interrupt flags. If 0 is specified then no interrupt thread is to be associated with this handler, in other words the handler will never call SignalRtInterruptThread. If a non-0 value is specified then this is the number of outstanding SignalRtInterruptThread requests that can exist. When this limit is reached the interrupt is disabled. The maximum value possible is 255.
Note: for PCI interrupts and MSI, set this value to 0 or 255 only. See remarks below.
lpfnHandler
Pointer to the interrupt handler.
lpParamPtr
A pointer which is passed into the shared interrupt handler whenever an interrupt occurs. If the specified interrupt is not shared and not MSI_LEVEL, then this parameter is ignored.

Remarks

The number of outstanding SignalRtInterruptThread requests that the handler can make before the associated interrupt level is disabled generally corresponds to the number of buffers used by the handler and interrupt thread.

If the byMaxInt parameter is non-zero, then the calling thread becomes the interrupt thread. If the interrupt source is a PCI legacy interrupt or an MSI, it is recommended that this value is set to the maximum, 255. If a small value is provided there is the risk that interrupts will be lost.

If the interrupt source is a legacy IRQ from a PCI device, assume that the interrupt line may be shared and logical-or the level parameter with SHARED_LEVEL before making the call.

If the interrupt level parameter is not OR-ed with SHARED_LEVEL and is not MSI_LEVEL then the interrupt handler will have the same form as for SetRtInterruptHandler.

If the interrupt source is an MSI then specify MSI_LEVEL for the wLevel parameter. In this case the lpParamPtr must point to an initialized MSI_PARAM or MSI_PARAM_EX structure. See the section about MSI handling for more detail.

The interrupt handler has this general form:

__INTERRUPT void InterruptHandler(
    WORD wCSRA,                 // (unused)
    WORD wLevel,                // interrupt level returned from SetRtInterruptHandlerEx
    PVOID pv)                   // parameter pointer from SetRtInterruptHandlerEx
{
    // TODO: any local variables are declared here.

    __SHARED_INTERRUPT_PROLOG();

    // TODO: interrupt handling statements

    __SHARED_INTERRUPT_RETURN();
}

Note that any pointer to a variable on the stack in the interrupt handler cannot be dereferenced. This is because the interrupt handler runs in a privileged context which makes it impossible for the compiler to generate a correct stack-based address. Any attempt to do so will result in a page fault.

To uninstall an interrupt handler call ResetRtInterruptHandler. If a handler has an associated interrupt thread then an implicit call to ResetRtInterruptHandler is made on exit from the current process. If there is no interrupt thread then an explicit call to ResetRtInterruptHandler must be made before process termination. Failure to do so can cause system instability.

Return Values

Success: returns a unique interrupt level value which should be used for all subsequent interrupt calls.
Failure: returns BAD_LEVEL. To determine the status, call GetLastRtError.

Status

E_OK 0000
No exceptional conditions occurred.
E_LIMIT 0x0004
Both of these conditions exist:
  • byMaxInt contains a value other than 0 (zero).
  • The interrupt level has an associated priority which is greater (numerically less) than the maximum allowed by the calling thread's process. See SetRtProcessMaxPriority.
E_CONTEXT 0x0005
One of these conditions exist:
  • The thread is already an interrupt thread.
  • The specified level already has an interrupt handler assigned, and does not allow sharing.
  • The specified level already has a shared handler assigned, but the caller does not want to share.
  • The process that contains the calling thread or the calling thread itself is being deleted.
E_PARAM 0x8004
One or more of these conditions exist:
  • wLevel is invalid.
  • The hardware configuration does not include a PIC for the specified level.
  • A non-null lpParamPtr parameter was specified for a non-shared interrupt level.
  • The specified level has not been reserved for INtime use. Use the INtime Device Configuration applet to reserve the interrupt.
E_BAD_ADDR 0x800F
The pointer to the interrupt handler is invalid. One of these conditions exist:
  • All or part of the interrupt handler is outside the calling thread's virtual address space.
  • The virtual address space has no associated physical memory.

Requirements

Versions Defined in Include Link to
INtime 3.0 intime/rt/include/rtbase.h rt.h rt.lib
See Also

PCI

Processes