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.

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

• InterruptMask()<br />

• InterruptUnmask()<br />

• InterruptLock()<br />

• InterruptUnlock()<br />

• InterruptDisable()<br />

• InterruptEnable()<br />

• in*() and out*()<br />

Basically, the rule of thumb is, “Don’t use anything that’s going to take a huge amount<br />

of stack space or time, and don’t use anything that issues kernel calls.” The stack<br />

space requirement stems from the fact that ISRs have very limited stacks.<br />

The list of interrupt-safe functions makes sense — you might want to move some<br />

memory around, in which case the mem*() and str*() functions are a good choice.<br />

You’ll most likely want to read data registers from the hardware (in order to save<br />

transitory data variables and/or clear the source of the interrupt), so you’ll want to use<br />

the in*() and out*() functions.<br />

What about the bewildering choice of Interrupt*() functions? Let’s examine them in<br />

pairs:<br />

InterruptMask() and InterruptUnmask()<br />

These functions are responsible for masking the interrupt source at the PIC<br />

level; this keeps them from being passed on to the CPU. Generally, you’d use<br />

this if you want to perform further work in the thread and can’t clear the source<br />

of the interrupt in the ISR itself. In this case, the ISR would issue<br />

InterruptMask(), and the thread would issue InterruptUnmask() when it had<br />

completed whatever operation it was invoked to do.<br />

Keep in mind that InterruptMask() and InterruptUnmask() are counting — you<br />

must “unmask” the same number of times that you’ve “masked” in order for the<br />

interrupt source to be able to interrupt you again.<br />

By the way, note that the InterruptAttachEvent() performs the InterruptMask()<br />

for you (in the kernel) — therefore you must call InterruptUnmask() from your<br />

interrupt-handling thread.<br />

InterruptLock() and InterruptUnlock()<br />

These functions are used to disable (InterruptLock()) and enable<br />

(InterruptUnlock()) interrupts on a single or multiprocessor system. You’d want<br />

to disable interrupts if you needed to protect the thread from the ISR (or<br />

additionally, on an SMP system, the ISR from a thread). Once you’ve done your<br />

critical data manipulation, you’d then enable interrupts. Note that these<br />

functions are recommended over the “old” InterruptDisable() and<br />

InterruptEnable() functions as they will operate properly on an SMP system.<br />

April 30, 2009 Chapter 4 • Interrupts 187

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

Saved successfully!

Ooh no, something went wrong!