attach a handler to a hardware interrupt
#include <sys/irqinfo.h>
int qnx_hint_attach(
unsigned intnum,
pid_t (* handler)(void),
unsigned ds );
/* Note, in the 16-bit libraries,
the prototype is: */
int qnx_hint_attach(
unsigned intnum,
pid_t (__far * __far handler)(void),
unsigned ds );
The qnx_hint_attach() function attaches the interrupt function handler to hardware interrupt intnum, where intnum must be between 0 and 15, inclusive, on an AT.
The following list contains typical interrupt assignments. Note that a request for interrupt 2 on an AT is changed to interrupt 9, since 2 is used internally to connect the slave 8259.
| Interrupt | Assignment |
|---|---|
| -1 | fixed 50 ms timer |
| 0 | timer |
| 1 | keyboard |
| 2 | slave |
| 3 | com2 |
| 4 | com1 |
| 5 | net card / other |
| 6 | floppy |
| 7 | parallel printer / net card / other |
| 8 | realtime clock |
| 9 | remapped interrupt 2 |
| 10 | |
| 11 | |
| 12 | |
| 13 | NDP co-processor |
| 14 | AT hard disk |
| 15 | second hd controller (standard) |
If you pass a value of (-1) for intnum, your handler is invoked every 50 milliseconds. This time period won't change, even if you program the physical timer (interrupt 0) to run faster using the clock_setres() function. This timer interrupt is driven from the timer, and scaled in software, to provide a fixed time interval of 50 milliseconds.
Most functions in the system library are compiled with stack checking disabled; routines that require a significant amount of stack might not. The latter tend to be functions that may not be called at interrupt time anyway, such as printf() and open(). If your functions contain any auto variables on the stack, we highly recommend that you place the interrupt function in its own file and compile it with the -zu option, which instructs the compiler that SS != DS.
Any variables modified by the handler should be specified with the volatile keyword.
The return value of the handler function must be 0, or a valid proxy pid that will be triggered to send a message.
If you are the first process to attach to the interrupt, the interrupt is unmasked. When the last process detaches from an interrupt the system masks it.
The following important guidelines should be followed when writing interrupt handlers:
The qnx_hint_attach() function returns an interrupt handler ID (a small positive int) on success. On error, a (-1) is returned, and errno is set.
errno, qnx_hint_detach(), qnx_hint_query()
/*
* Please note that stack checking must be disabled in your
* handler. You can use the pragmas below and/or the
* "-Wc,-s" option to the CC command.
*/
#include <stdio.h>
#include <sys/irqinfo.h>
#include <sys/proxy.h>
#include <sys/kernel.h>
pid_t proxy;
volatile unsigned counter;
/* The hardware interrupt handler */
#pragma off( check_stack );
pid_t far handler()
{
/* Kick a proxy every 100 timer interrupts */
if( (++counter % 100) == 0 )
return( proxy );
return( 0 );
}
#pragma on( check_stack );
void main()
{
int id, i;
/* Get a proxy for the interrupt handler to kick */
if( ( proxy = qnx_proxy_attach( 0, 0, 0, 0 ) )
== -1 ) {
printf( " Unable to attach proxy. " );
return;
}
/* Attach to the timer */
if( ( id = qnx_hint_attach( 0, &handler,
FP_SEG( &counter ) ) ) == -1 ) {
printf( "Unable to attach interrupt." );
return;
}
/* Wait for the proxy */
for( i = 0 ; i < 10 ; ++i ) {
Receive( proxy, 0, 0 );
printf( "100 ticks.\n" );
}
qnx_hint_detach( id );
}
QNX
QNX