Interrupt calls

QNX SDP8.0System ArchitectureDeveloperUser

The interrupt-handling API includes the kernel calls listed here.

Function Description
InterruptAttachThread() Attach a local function (an Interrupt Service Thread or IST) to an interrupt vector. This is the preferred call.
InterruptAttachEvent() Generate an event on an interrupt, which will ready a thread.
InterruptDetach() Detach from an interrupt using the ID returned by InterruptAttachThread() or InterruptAttachEvent().
InterruptWait() Wait for an interrupt.
InterruptEnable() Enable hardware interrupts.
InterruptDisable() Disable hardware interrupts.
InterruptMask() Mask a hardware interrupt.
InterruptUnmask() Unmask a hardware interrupt.

Using this API, a suitably privileged user-level thread can call InterruptAttachThread() or InterruptAttachEvent(), passing a hardware interrupt number to associate itself or an event with that interrupt number.

Note:
  • The startup code is responsible for making sure that all interrupt sources are masked during system initialization. When the first call to InterruptAttachThread() or InterruptAttachEvent() is done for an interrupt vector, the kernel unmasks it. Similarly, when the last InterruptDetach() is done for an interrupt vector, the kernel remasks the level.
  • You should disable interrupts for as little time as possible (i.e., the minimum time you need to access or deal with the hardware). Failure to do so may result in increased interrupt latency and the inability to meet realtime deadlines.
  • Kernel calls and some library routines reenable interrupts. Masked interrupts aren't affected.
The following code sample shows how to attach a thread to an interrupt source:
#include <sys/neutrino.h>

#define IRQ_NUM 76

void* hardware_ist(void *unused)
{
    // Attach this thread to the interrupt source.
    int const id = InterruptAttachThread(IRQ_NUM, _NTO_INTR_FLAGS_NO_UNMASK);
    if (id == -1) {
        // Handle errors.
    }

    for (;;) {
        // Wait for the interrupt to assert.
        // The FAST flag is more efficient, but cannot handle timeouts.
        int const rc = InterruptWait(_NTO_INTR_WAIT_FLAGS_UNMASK |
                                     _NTO_INTR_WAIT_FLAGS_FAST, NULL);
        if (rc == -1) {
            // Handle errors.
        }

        // Handle the interrupt. The interrupt is masked and will not be asserted again
        // until InterruptWait() is called again with the UNMASK flag.
    }
}

With this approach, appropriately privileged user-level threads can dynamically attach to (and detach from) hardware interrupt vectors at runtime. These are regular OS threads, and thus can be debugged using regular source-level debug tools, and the priority of the work generated by hardware interrupts can be performed at OS-scheduled priorities rather than hardware-defined priorities.

For more information about interrupts, see the Interrupts chapter of Getting Started with the QNX OS, and the Handling Hardware Interrupts chapter of the QNX OS Programmer's Guide.

Page updated: