Interrupts and Pulses

I am experimenting with interrupts in QNX and I was wondering if somebody could let me know how to clear the interrupt source in the case of notification being made via a pulse? I am using the parallel port and programs run fine with sigev_notify = SIGEV_INTR and an ISR but the int lint stays high if I use pulse notification. I understand there is no need to send an EOI (end of interrupt) to the PIC in QNX as would be the case with DOS (and I don’t send one when I use SIGEV_INTR).
As always, all suggestions are much appreciated!

It seems that the code that you have in the thread that does the InterruptWait is correctly clearing the device doing the interrupt, whilst the code you have doing the MsgReceive to get the pulse is not. QNX will automatically mask the IRQ so that the interrupt handler is not re-entered (which would crash the kernel) but your interrupt handler is still responsible for clearing the device, so that the IRQ is de-asserted, before calling InterruptUnmask.

Using InterruptWait, I do not explicitly acknowledge the parallel port interrupt, I simply return an event from the isr (and do nothing else!) which unblocks InterruptWait and the code below that excutes for each interrupt. This appears to deassert the (interrupt) line ok.
Using Pulses as notification, obviously there is no isr and as I am not supposed to issue an EOI I do not know how I am supposed to ack the interrupt to deassert the line in this case?

The ISR isn’t what causes the interrupt to be ack’d., it will be in the code that runs after the InterruptWait() unblocks.

The common old ISA based parallel ports use edge based interrupts and don’t have any method of ack’ing the interrupt so there is no extra coding required in that part. ie: It can not be shared with any other interrupt source.

I would be looking more carefully at the return value of the ISR or at the pulse handling.

I have looked at the different versions of the programs and the differences that appear in the parallel port status register for each program run. With the pulse version there seems to be some extra calls to InterruptMask made by the kernel. (InterruptMask is called automatically only on InterruptAttachEvent??)
When I added the code :

// intrMaskNum is the num of calls to InterruptMasks that have occurred…
while(intrMaskNum >0) {
printf(“Interrupt unmasked with num %d\n”,intrMaskNum);
intrMaskNum = InterruptUnmask( INTERRUPT_NUMBER, intr_funct_ID );
errvalue = errno;
printf(“Error unmasking interrupt:%s”,strerror( errvalue ) );
}// end if
}// end while

everything worked fine. I am still a little uneasy however, as I do not fully understand why InterruptUnmask should be called more than once unless I am doing something else wrong? It does not need to be called at all if the notification type is set to INTR.

Yes, with InterruptAttachEvent() the kernel will automatically mask the interrupt for you. Feel free to post your entire code if you like. You should only have to unmask the interrupt once.

Guys, if you use edged interrupt, can you mask interrupts at all (you might loose them)?
As i would do in this case - just do interrupt handler, and send your interrupt event (do not mask interrupts). And dont use InterruptAttachEvent, because it masks interrupts for you.

BTW, i don’t think qnx is masking interrupts to avoid reentrance. As i know, it just waits until all handlers done and then enables new interrupt for this level (out 20,20 or out 20,a0) :slight_smile:

Well the OP did not originally specify that he was using edge triggered interrupts. Yes, there is no need for interrupts to be masked if the IRQ is edge triggered, and no, even if you did use InterruptAttachEvent (which would mask the interrupt), the masking would not (in practical terms) result in loosing any interrupts, since this is QNX (not Windows) we’re dealing with.

Assuming you give the pulse that you attach a sufficiently high priority, you will service the interrupt before the next one comes in (this ability to guarantee things like this, is why QNX is referred to as a RTOS).

Yes it is. RTFM InterruptMask().

Seeing that QNX is a RTOS, you really shouldn’t be writing interrupt handlers at all (since they are not schedulable entities, and as such violate the precepts of real-time).

The way that interrupts should typically be handled is either via InterruptAttachEvent or InterruptWait.

IMHO, masking interrupts and enabling interrupts are kind of different things. When you mask them you don’t allow PIC to interrupt specific level. When you enable interrupts, you enable them for this and lower level. BTW, InterruptMask manual does not say that qnx masking interrupts.