NI-6602 + QNX Interrupts

Hello Guys,

i need help with the Interrupt System in QNX. The card mentioned above shall count down i.e. from 0x3000 down to 0, then generate an interrupt. And this is, where I’m stuck. Is it enough to make an “InterruptAttach()” to the IRQ I got from the pci_dev_info struct, after i called “pci_attach_device()” ?
The sense of it is to make a function like sleep() or nanosleep(), so the counter card is initialized with a value and then (the call to it) blocks as long as no interrupt arrives.
I would appreciate every help.

Thanks

The answer to your question depends on your hardware. Sometimes, along with initializing the count-down timer, you you have to set a Interrupt-enable bit in a register, so that the interrupt your hardware is causing, is attached to the interrupt controller. Typically if this is the case, there is also a readable register with a bit that tells you that the interrupt has fired, so that you can poll if necessary.
If you make a function as you describe, you might want to set up a QNX timer before you start waiting, so that you would accidentally block forever if there is a hardware problem/glitch.

Thanks for the reply. Polling is something I don’t want to use, that’s why I want Interrupts. But it seems to work now, just needed to take a look in the programmer’s guide, but one question is still there. In Chapter 6 on page 234/235 the “isr_handler()” returns an (&event). This should be decalared in the main function. Now the question:
Do I need to pass the “struct sigevent event” from the main method to the “int_thread” and then pass it further to the isr_handler(…,void* xyz,…) as xyz, because now, it’s defined as a global variable, but that isn’t clean, in my opinion.

The point about polling is not that you should poll. During debugging, if you are not seeing an interrupt, you can read a bit which will tell you whether the device has interrupted or not. If it has, then it would mean you haven’t set up your ISR correctly.

Maybe I misunderstand you, but you would not want to declare “event” as a local variable in main().
Your stack data is not even available when in the ISR. That leaves only two possibilities, event as a global, or as a local variable for the isr. I don’t think that the latter will work.

This might not seem “clean” from your experience, but an ISR is practically at the raw hardware level. The ‘C’ or C++ languages bow to the will of the processor architecture, not the other way around. I suppose QNX could have designed the ISR interface so that you get passed an event structure, but they didn’t.

You CAN pass a pointer to the interrupt handler. It the area and size field.

Thank you again, now I understand what you meant, but my ISR seems to work correctly now. Bits are set during the interrupt and cleared during the ISR.

With the “event”; I declared it in the ISR and it works fine, my problem was just this:

the last comment :"…preinitialized by main…" ; it confused me a bit, so I searched for a way to initialize it in main() and pass it to the ISR…

Another problem, the voidarg parameter of the ISR is the only way to do a communiction of the ISR and the interrupt_thread. Now my parameter is an object discribing my board (board). But how to pass a second parameter? I need to pass the used IRQ (for an “InterruptMask(IRQ,NULL)”), so i need to pass the “info.Irq”-Variable of my “struct pci_dev_info info”. The only way I see here, is to make a struct or an array of {board,irq} and pass this one. Or is there another way, that I don’t see?

making a struct that contains board and irq data is the way to go aside global variables.

Personally I don’t have a problem with global variable. I make it static and then use fonctions to allow other modules to set/get that variable.

So that’s a non-global global, eh?! ;-)

LOL

Colin

Horst,

I am programming a PCI-6034E, and I am having problems implementing an ISR; please let me know whether you have solved your problems.  I would like to share my code, and I would love to see the code that you used to set the IRQ (I use the ESeries and STC objects with osiBus) and how your code executes following the ISR call.

Thanks very much,

Joe

It’s a private global with member access functions. I don’t have any problem with those either :slight_smile:

Nice way to sell ADT without offending the hacker types Mario! I have officially added that one to my bag of tricks :slight_smile: