Is it neccessary to use I.A. or I.A.E.

Hi All,
I have a doubt regarding interrupts. In the QNX interrupts are registered either by InterruptAttach or InterruptAttachEvent. In my driver implementation, i am not using I.A or I.A.E but creating a thread for my ISR with polling mechanism ( at 500nsec internal ISR called).
Please let me know creating a thread for handling the interrupt is correct?? (I am doing this because after using I.A. my ISR is not called)

Gary,

This isn’t correct.

If you are creating a thread that runs at 500 nsec then you don’t have an interrupt you have a polling mechanism. In any case you are likely to find that your 500 nsec (< 1 ms) polling rate can’t be met by the O/S reliably.

You should instead try to figure out why your ISR code isn’t being called wehn you are using IA. Because it most certainly should be if you implemented it correctly. However you are much better off going with IAE over IA. because you can debug IAE code in the debugger and won’t crash the O/S if you make a mistake.

Why don’t you post your code.

Tim

Hello All,
I have wrote IAE in following manner to service the interrupts generated on board.

int interruptID;
void *isr_handler();

int main()
{
pthread_attr_t attrib;
struct sched_param param;

Resource manager stuff

pthread_attr_init (&attrib);
pthread_attr_setinheritsched (&attrib, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy (&attrib, SCHED_RR);
param.sched_priority = 20;
pthread_attr_setschedparam (&attrib, &param);
pthread_create(NULL, &attrib, isr_handler, NULL);

ctp = dispatch_context_alloc (dpp);

}

void *isr_handler()
{
slogf(_SLOG_SETCODE(_SLOGC_CHAR,0),_SLOG_INFO,“isr_handler called”);

struct sigevent event;

memset(&event, 0, sizeof(event));
event.sigev_notify=SIGEV_INTR;     // Kernel send this event, whenever write, read etc interrupts are generated.

interruptID = InterruptAttachEvent(9,&event, 0); // 9 is the irq line number for hardware
if (interruptID == -1)
{
	fprintf(stderr,"Could not attach IRQ in hardware .\n");
	return NULL;
}

while(1) 
{
	fprintf(stderr,"** InterruptWait is blocked **\n");
	 InterruptWait(0,NULL);
	 fprintf(stderr,"InterruptWait is unblocked\n");
	// Handle the ISR, if InterruptWait unblocked.
}

}

      As per the code isr_handler will be called and InterruptWait is waiting for a SIGEV_INTR event. Interruptwait will be unblock if kernel send SIGEV_INTR to driver. 
       The problem is after writing or reading data on port an ISR thread is not unblocked and keep waiting for a SIGEV_INTR event for unblocking. The IRQ line is correct.
    In polling mechanism, my writing and reading is working fine on hardware port and hardware registers are changed for indication of interrupts in global status register.

Gary,

Where in your code are you doing the ThreadCtrl() call to get I/O privileges? This must be done in the isr_handler() thread itself, not in main() and I don’t see it in your code.

Also I don’t see the InterruptUnmask() call in your isr_handler() code to re-enable the interrupt. So I’d expect your interrupt handler to get called one time only.

Tim

Yes tim you are correct, ThreadCtrl() was called only in the main function and not in the ISR thread. But IAE in isr_handler worked fine and won’t rerurn -1?
Regarding the InterruptUnmask(), it was used in the isr_handler and not shown in code. Actually my isr is very lengthy thats not pasted entire code. Anyway i will check about ThreadCtl() and update you.

Hi ,
I have modified the code as you suggested but still interrupt event is not coming. An isr thread is keep waiting at InterruptWait. Please have a look on my code ,

void *isr_thread(void *arg)
{
int interruptID;
int ret;
struct sigevent event;

slogf(_SLOG_SETCODE(_SLOGC_CHAR,0),_SLOG_INFO,“isr_thread called”);
ThreadCtl(_NTO_TCTL_IO, 0);

SIGEV_INTR_INIT( &event );

interruptID = InterruptAttachEvent(9,&event,_NTO_INTR_FLAGS_TRK_MSK);
if (interruptID == -1)

{
fprintf(stderr,“Could not attach IRQ in Hardware .\n”);
return NULL;
}

while(1)
{
fprintf(stderr,"* InterruptWait is blocked * \n");
ret = InterruptWait(NULL,NULL); // HERE ISR THREAD KEEP WAITING FOR Interrupt Event.
if(ret == -1)
slogf(_SLOG_SETCODE(_SLOGC_CHAR,0),_SLOG_INFO,“InterruptWait is failed”);

    fprintf(stderr,"InterruptWait is unblocked\n");

  // Handle the hardware interrupts here.
  InterruptUnmask(9, interruptID);
}

}

   What are the probable causes for not getting interrupt? I am 100 % sure that my irq line number is 9 and all interrupt related hardware registers updated on write and read interrupt.

Then only the obvious remains, the interrupt isn`t generated. try attatchin to interrupt o, which DOES happen. That will tell you if you isr is setup right or not

Hi ,
I have used irq line number 0 for attaching the interrupt and ISR worked fine. The InterruptWait is unblocked in while(1) loop. So it confirms me that QNX side there is no issue and my card is not initilized properly ( please confirm mario).
But still don’t understand if initialization has problem then why in polling mechanism data writing and reading happenng. Please help me out if anybody any suggestions.
I have set the interrupt in Push/ pull active high mode.

Something is definitely not setup right with the hardware without more detail there isn’t much more I can say. As far as I’m concern this goes beyond the scope of this forum.

This is why programers (and I mean programmers, not engineers who dabble) who love hardware are few and far between. The nature of software is consistent reliable behavior. With hardware there are problems. Sometimes there is no software solution. Sometimes the hardware is defective, flaky, incorrectly or more likely sparsely documented. Now I’ll step down from the soap box and answer a question.

The reason the hardware may work even though the IRQ isn’t firing is because often you have to set a register bit to cause the firing to happen. Most of the hardware with IRQ that I’ve worked on can be built to work in a polling mode. Sometimes it will even work efficiently and effectively that way. Adding the IRQ just returns the lost polling cycles and sometimes better response. Don’t laugh, sometimes worse response. Of course polling can have a very negative affect on the overall performance of a system.

Thanks alot to all of you for sharing your knowledge on QNX device driver.

Hi All,
To solve my problem, i need migration help for porting my driver from QNX 4.25 to QNX neutrino. I got the source code of migration kit and compile code of entire src folder. That includes lib, services and utils folder. So i created 2 different project for mig4nto utility, mig4nto-procmgr service and one share library called mig4nto.
Issue 1: Then i have placed the libmig4nto.so.1 file to following path \usr\QX640\target\qnx6\x86\lib and execute mig4nto utility but it says “MIG4NTO: “/etc/mig4nto.tab” file does not exist”.
How to get mig4nto.tab file ???

         Issue 2: I am getting following message during running the mig4nto-procmgr service "Could not load library libmig4nto.so.1". But libmig4nto.so.1 is available in \usr\QX640\target\qnx6\x86\lib.

 I just wanted to check, is there any porting mistake done by me.

Note : I am using mig4nto utility in QNX neutrino.