26.02.2014 Views

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Writing interrupt handlers<br />

© 2009, <strong>QNX</strong> <strong>Software</strong> <strong>Systems</strong> GmbH & Co. KG.<br />

Attaching <strong>with</strong> InterruptAttachEvent()<br />

Attaching <strong>with</strong> InterruptAttach()<br />

The InterruptAttachEvent() function takes two additional arguments: the argument<br />

event, which is a pointer to the struct sigevent that should be delivered, and a<br />

flags parameter. InterruptAttachEvent() tells the kernel that the event should be<br />

returned whenever the interrupt is detected, and that the interrupt level should be<br />

masked off. Note that it’s the kernel that interprets the event and figures out which<br />

thread should be made READY.<br />

With InterruptAttach(), we’re specifying a different set of parameters. The handler<br />

parameter is the address of a function to call. As you can see from the prototype,<br />

handler() returns a struct sigevent, which indicates what kind of an event to<br />

return, and takes two parameters. The first passed parameter is the area, which is<br />

simply the area parameter that’s passed to InterruptAttach() to begin <strong>with</strong>. The second<br />

parameter, id, is the identification of the interrupt, which is also the return value from<br />

InterruptAttach(). This is used to identify the interrupt and to mask, unmask, lock, or<br />

unlock the interrupt. The fourth parameter to InterruptAttach() is the size, which<br />

indicates how big (in bytes) the data area that you passed in area is. Finally, the flags<br />

parameter is the same as that passed for the InterruptAttachEvent(); we’ll discuss that<br />

shortly.<br />

Now that you’ve attached an interrupt<br />

At this point, you’ve called either InterruptAttachEvent() or InterruptAttach().<br />

Since attaching an interrupt isn’t something you want everyone to be able to do,<br />

<strong>Neutrino</strong> allows only threads that have “I/O privileges” enabled to do it (see the<br />

ThreadCtl() function in the <strong>Neutrino</strong> Library Reference). Only threads running from<br />

the root account or that are setuid() to root can obtain “I/O privileges”; hence we’re<br />

effectively limiting this ability to root.<br />

Here’s a code snippet that attaches an ISR to the hardware interrupt vector, which<br />

we’ve identified in our code sample by the constant HW_SERIAL_IRQ:<br />

#include <br />

int interruptID;<br />

const struct sigevent *<br />

intHandler (void *arg, int id)<br />

{<br />

...<br />

}<br />

int<br />

main (int argc, char **argv)<br />

{<br />

...<br />

interruptID = InterruptAttach (HW_SERIAL_IRQ,<br />

intHandler,<br />

&event,<br />

176 Chapter 4 • Interrupts April 30, 2009

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!