InterruptAttachEvent(), InterruptAttachEvent_r()

Attach an event to an interrupt source

Synopsis:

#include <sys/neutrino.h>

int InterruptAttachEvent( 
       int intr,
       const struct sigevent* event,
       unsigned flags );

int InterruptAttachEvent_r( 
       int intr,
       const struct sigevent* event,
       unsigned flags );

Arguments:

intr
The interrupt vector number that you want to attach an event to; for more information, see Interrupt vector numbers in the documentation for InterruptAttach().
event
A pointer to the sigevent structure that you want to be delivered when this interrupt occurs.
flags
Flags that specify how you want to attach the interrupt handler; a bitwise OR of zero or more of the following:
  • _NTO_INTR_FLAGS_END
  • _NTO_INTR_FLAGS_NO_UNMASK (QNX Neutrino 6.6 or later)
  • _NTO_INTR_FLAGS_PROCESS
  • _NTO_INTR_FLAGS_TRK_MSK
  • _NTO_INTR_FLAGS_EXCLUSIVE (QNX Neutrino 7.0.4 or later)

For more information, see Flags,” below.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The InterruptAttachEvent() and InterruptAttachEvent_r() kernel calls attach the given event to the hardware interrupt specified by intr. They automatically enable (i.e., unmask) the interrupt level. These functions are identical except in the way they indicate errors. See the Returns section for details.

Before calling either of these functions, the process must have the PROCMGR_AID_INTERRUPTEVENT or PROCMGR_AID_INTERRUPT ability enabled. For more information, see procmgr_ability().

If the thread doesn't have the appropriate abilities, the call to InterruptAttachEvent() fails with an error of EPERM.

To prevent infinite interrupt recursion, the kernel automatically does an InterruptMask() for intr when delivering the event. After the interrupt-handling thread has dealt with the event, it must call InterruptUnmask() to reenable the interrupt.

Consider the following when choosing an event type:

On a multicore system, the thread that receives the event set up by InterruptAttachEvent() runs on any CPU, limited only by the scheduler and the runmask.

Flags

The flags argument is a bitwise OR of zero or more of the following values:

_NTO_INTR_FLAGS_END
Put the new event at the end of the list of existing events instead of the start.

The interrupt structure allows hardware interrupts to be shared. For example if two processes call InterruptAttachEvent() for the same physical interrupt, both events are sent consecutively. When an event attaches, it's placed in front of any existing events for that interrupt and is delivered first. You can change this behavior by setting _NTO_INTR_FLAGS_END.

_NTO_INTR_FLAGS_NO_UNMASK
(QNX Neutrino 6.6 or later) Leave the interrupt masked.

Normally, InterruptAttach() and InterruptAttachEvent() automatically unmask an interrupt the first time something is attached to it. If you specify _NTO_INTR_FLAGS_NO_UNMASK, the kernel leaves the interrupt masked, and you must specifically call InterruptUnmask() to enable it.

_NTO_INTR_FLAGS_PROCESS
Associate the interrupt event with the process instead of the attaching thread. The interrupt event is removed when the process exits, instead of when the attaching thread exits.
Note: The kernel automatically sets the _NTO_INTR_FLAGS_PROCESS flag if the event is directed at the process in general (for SIGEV_SIGNAL, SIGEV_SIGNAL_CODE, and SIGEV_PULSE events).
_NTO_INTR_FLAGS_TRK_MSK
Track calls to InterruptMask() and InterruptUnmask() to make detaching the interrupt handler safer.

The _NTO_INTR_FLAGS_TRK_MSK flag and the id argument to InterruptMask() and InterruptUnmask() let the kernel track the number of times a particular interrupt handler or event has been masked. Then, when an application detaches from the interrupt, the kernel can perform the proper number of unmasks to ensure that the interrupt functions normally. This is important for shared interrupt levels.

Note: You should always set _NTO_INTR_FLAGS_TRK_MSK.
_NTO_INTR_FLAGS_EXCLUSIVE
(QNX Neutrino 7.0.4 or later) Request exclusive access to the interrupt vector. If another thread already called an InterruptAttach*() function with the same vector, this kernel call fails with an EBUSY error. Similarly, if this call succeeds but another thread later calls an InterruptAttach*() function with the same vector, that call fails with the same error.

Advantages & disadvantages

InterruptAttachEvent() has several advantages over InterruptAttach():

There are also some disadvantages:

You can freely mix calls to InterruptAttach() and InterruptAttachEvent() for a particular interrupt.

Blocking states

These calls don't block.

Returns:

An interrupt function ID. If an error occurs:

Use the ID with InterruptDetach() to detach this interrupt event.

Errors:

EAGAIN
All kernel interrupt entries are in use.
EFAULT
A fault occurred when the kernel tried to access the buffers provided.
EINVAL
The value of intr isn't a valid interrupt number.
EPERM
The process doesn't have the required permission; see procmgr_ability().

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes