ISR is not calling..

Hi,

I am working on a device driver of cPci board. In which Interrupt concept is needed.
for this purpose i implemented a below code but its not working

struct sigevent SigInt;
int id;
short sRetVal = 0;
main()
{
ThreadCtl( _NTO_TCTL_IO, 0 )
sRetVal = pthread_create(&Threadid,&Threadattr,&DRV_ISR_CntlModule,&devicecontext);
if(sRetVal != 0)
{
printf(“Control Module Thread Creation Error: %d\n”,sRetVal);
}

DRV_ISR_CntlModule()
{
ThreadCtl( _NTO_TCTL_IO, 0 )
SIGEV_INTR_INIT(&SigInt);

id = InterruptAttach(Irqnumber,DP_DEV_ISR, pSDevContext, sizeof(pSDevContext), (_NTO_INTR_FLAGS_TRK_MSK|_NTO_INTR_FLAGS_END));
if(sRetVal < 0)
{
printf("\n interruptattach failed   \n");
return -1;
}
while (1) 
{
	printf("\n\t\t    InterruptWait is called......\n");
	iRetVal = InterruptWait(0,NULL);
	if(iRetVal == -1)
	{
		printf("InterruptWait Fail\n");	
	}
	printf("Interrupt event SIGINT Received\n");
	InterruptUnmask(Irq,id);
	//rsi = (*DP_DEV_ISR)(pSDevContext, id);
	printf("ISR calling ......\n");	
}

}

please provide any suggestion to call ISR

Thanks in Advance to all…

Hi,

You say “code is not working”. What does that mean ? Nothing happen ? Errors are returned ?
I guess nothing happens. There is nothing in your code enabling interrupts on the device.

Few remarks :

  • You do not need to call ThreadCtl() in main and in thread. Threads inherit their parent.
  • Format your code correctly. The one you posted is hard to read.

[size=150][size=150][size=150]Hi,

NICO04, Thanks for the reply…

I have modifed the above code and formatted…
kindly give suggestion to the problem.

Target Platform: QNX 6.5
/*********************************************************************/

//header files

struct sigevent SigInt;
typedef struct pci_dev_info BUS_DEV;
BUS_DEV BusDevInfo;

main()
{
short sRetVal = 0;
pthread_t Threadid;
pthread_attr_t Threadattr;

BUS_DEV BusDevInfo.Irq = 7; // this Irq number is given by pci_attach_device system call

ThreadCtl( _NTO_TCTL_IO, 0 );

pthread_attr_init( &Threadattr);
pthread_attr_setdetachstate(&Threadattr, PTHREAD_CREATE_DETACHED);

sRetVal = pthread_create(&Threadid, &Threadattr, &ISR_CntlModule, &devicecontext);

if(sRetVal != 0)
{
	printf("Control Module Thread Creation Error: %d\n",sRetVal);
}

}

void* ISR_CntlModule(void * in_Handle)
{
int iRetVal = 0 ;
int InterruptAttachId;

//ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT(&SigInt);

/*Enabling Hardware Interrupts*/
InterruptEnable();

InterruptAttachId = InterruptAttach(BusDevInfo.Irq, ISR, in_Handle, sizeof(in_Handle), (_NTO_INTR_FLAGS_TRK_MSK|_NTO_INTR_FLAGS_END));
	
if(InterruptAttachId == -1)
{
	printf("\n interruptattach failed \n");
	return -1;
}
	
while (1) 
{
	printf("\n InterruptWait is called......\n");
			
	iRetVal = InterruptWait(0,NULL);
	
	if(iRetVal == -1)
	{
		printf("InterruptWait Fail\n");	
	}
	printf("Interrupt event SIGINT Received\n");
	
	/*Interrupt unmasking*/
	InterruptUnmask( BusDevInfo.Irq, InterruptAttachId );
	
	printf("ISR calling ......\n");	
}

}

/ISR function/
const struct sigevent* ISR(void * parameter, int id)
{
int s16RetVal = 0;
s16RetVal = ReadReg(); //reading the registers will happens here
return NULL;/Nothing can be handled in ISR_CntlModule thread/
}

/*********************************************************************/

In the above code , upto “InterruptWait” the thread is executing(InterruptWait is called… message is printing),
when the interrupt is generated, the “ISR” function (attached in InterruptAttach() system call)is not calling.

But when checking with “pidin irqs” command , It is showing the Handler address,Address of Area passed to Handler,IRQ number and
InterruptAttach id(12) as expected.

I didn’t configure “startup-bios” and “startup-apic”.
Is it required for irq number assignment?
If it is required how can i configure,where and when i can configure?[/size][/size][/size]

Please don’t use larger font. It makes your message harder to read.
When I requested you to format your code correctly, I meant you should use the “code” button above the edit box.

Your problem comes from the ISR function. It must return an event for InterruptWait() to unblock.
Please see an explanation here : qnx.com/developers/docs/6.6. … ttach.html

Hi,

NICO04, Thanks for the reply…

I have modifed the above code and formatted…
kindly give suggestion to the problem.

Target Platform: QNX 6.5
/*********************************************************************/

[code]//header files

struct sigevent SigInt;
typedef struct pci_dev_info BUS_DEV;
BUS_DEV BusDevInfo;

main()
{
short sRetVal = 0;
pthread_t Threadid;
pthread_attr_t Threadattr;

BUS_DEV BusDevInfo.Irq = 7; // this Irq number is given by pci_attach_device system call

ThreadCtl( _NTO_TCTL_IO, 0 );
	
sRetVal = pthread_create(NULL,NULL, &ISR_CntlModule, &devicecontext);

if(sRetVal != 0)
{
	printf("Control Module Thread Creation Error: %d\n",sRetVal);
}

}

void* ISR_CntlModule(void * in_Handle)
{
int iRetVal = 0 ;
int InterruptAttachId;

//ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT(&SigInt);

/*Enabling Hardware Interrupts*/
InterruptEnable();

InterruptAttachId = InterruptAttach(BusDevInfo.Irq, ISR, in_Handle, sizeof(in_Handle), (_NTO_INTR_FLAGS_TRK_MSK|_NTO_INTR_FLAGS_END));
	
if(InterruptAttachId == -1)
{
	printf("\n interruptattach failed \n");
	return -1;
}
	
while (1) 
{
	printf("\n InterruptWait is called......\n");
			
	iRetVal = InterruptWait(NULL,NULL);
	
	if(iRetVal == -1)
	{
		printf("InterruptWait Fail\n");	
	}
	printf("Interrupt event SIGINT Received\n");
	
	/*Interrupt unmasking*/
	InterruptUnmask( BusDevInfo.Irq, InterruptAttachId );
	
	printf("ISR calling ......\n");	
}

}

/ISR function/
const struct sigevent* ISR(void * parameter, int id)
{
int s16RetVal = 0;
s16RetVal = ReadReg(); //reading the registers will happens here
return &SigInt;
}

/*********************************************************************/[/code]

In the above code , upto “InterruptWait” the thread is executing(InterruptWait is called… message is printing),
when the interrupt is generated, the “ISR” function (attached in InterruptAttach() system call)is not calling.

But when checking with “pidin irqs” command , It is showing the Handler address,Address of Area passed to Handler,IRQ number and
InterruptAttach id(12) as expected.

I didn’t configure “startup-bios” and “startup-apic”.
I configured pci bios through the following command.“pci-bios -B”
Is it required for irq number assignment?
If it is required how can i configure,where and when i can configure?
Note:Here Interrupt is Legacy Interrupt not MSI

/*
Here I done one timer example which fires for every 1 sec and it will send event.
*/

[code]#include <stdio.h>
#include <time.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>

timer_t timer_id;
time_t timer;
struct sigevent event;
const struct sigevent * isr_handler(void * area,int id);
static volatile int g_iTemp;

/ISR Handler function/
const struct sigevent * isr_handler(void * area,int id)
{
printf(“In isr function****\n”);

InterruptMask(0,id);

    g_iTemp =  SYSPAGE_ENTRY(qtime);
//event.sigev_value.sival_int = 20;
return &event;

}

void Isr_Thread()
{
printf(“In Isr thread\n”);
event.sigev_notify = SIGEV_INTR;

	printf("Isr Thread Id:%d\n",pthread_self());
	//const struct sigevent * (*ISR_handler) (void *,int ) = &isr_handler;

       if(InterruptAttach(0, isr_handler, NULL, 0, 0) == -1)
   {
	   printf("\n\t\t InterruptAttach/Event Function failed \n");
	   return -1;
   }
   timer_create(CLOCK_REALTIME, &event, &timer_id);
   struct itimerspec       itime;
   	printf("Timer Thread Id:%d\n",pthread_self());
   	itime.it_value.tv_sec = 1;
   	   itime.it_value.tv_nsec = 0;
   	   itime.it_interval.tv_sec = 1;	   	  
   	   itime.it_interval.tv_nsec = 0;
   	   timer_settime(timer_id, 0, &itime, NULL);

   while(1)
   {
	   printf("ISR is waiting\n");
	   printf("Before Interrupt Wait event.sigev_value:%d\n",event.sigev_value.sival_int);
   	   InterruptWait (NULL, NULL);
   	   timer = time(NULL);
   	   printf("After Interrupt time is:%s\n",ctime(&timer));
   	   printf("Interrupt Came,so InterruptWait unblocked\n");
   	   printf("Value of g_iTemp:%d\n",g_iTemp);
   }

}

main()
{
struct itimerspec itime;
int id;
printf(“Main Thread Id:%d\n”,pthread_self());
/* Obtain I/O privileges */
ThreadCtl( _NTO_TCTL_IO, 0 );

timer = time(NULL);
printf("Before calling thread time is:%s\n",ctime(&timer));

/* Start the thread that will handle interrupt events. */
pthread_create (NULL, NULL, Isr_Thread, NULL);

char ch = 0;
printf(“Press enter to exit\n”);
scanf("%c",ch);

}[/code]

Question1:
After every 1 sec, timer is firing,“InterruptWait” is unblocking,But “isr_handler” is not called.
Because after Interrupt came, I checked the value of g_iTemp,but it’s value is 0 only why?

Question2:
If I comment “InterruptAttach” function also, Interrupt is generating.So It mean that for every
1 sec timer will fire irrespective of interrupt registration through “InterruptAttach” function.i.e timer will
fire for every 1 sec and it will notify through signal like SIGEV_INTR,SIGEV_PULSE(whoever waiting).
Am I correct?.If i am correct, in my case(Refer earlier post) FPGA is generating interrupt. But ISR function
is not calling.How can I solve this issue?

Writing “BUS_DEV BusDevInfo.Irq = 7;” is an error. You must get the value in the struct returned by pci_attach_device(). This value is dynamically determined at start-up by the BIOS.

How do you initialise pci access ? What are the arguments you pass to pci_attach_device() ?

You do not need to call InterruptEnable() unless you have called InterruptDisable() before.

There is no FPGA interrupt enable in your code.
There is no FPGA interrupt acknowledge in your code.

Note : It is recommended to use InterruptAttachEvent() instead of InterruptAttach().

—>IRQ No 7 is got from pci_attach_device call().

–>DevInfo is a variable of pci_dev_info structure.
–>Here iBrdIndex is incrementing based on boards found.Initial value of iBrdIndex is 0,for every board detection it will increment by one.
–>DevInfo.VendorId = MY_VENDOR_ID, DevInfo.DeviceId = MY_DEVICE_ID
–>pci_attach_device(NULL,PCI_INIT_ALL,iBrdIndex,&DevInfo);

–>We tried without InterruptEnable/Disable,in that case also isr not called.

—>I am calling Sample_InterruptEnable() function,there i am enabling a interrupt(By writing a proper value in FPGA Register).
Note:Here FPGA Interrupt status register is properly updating

—>Acknowledge menas clearing the interrupt?

—>InterruptAttachEvent also tried

In your code, you don’t get it from pci_attach_device() but you force it to 7.

There is no such call in your code.

I should have written “re-arm” the interrupt, which is often clearing it.

Try with the following :
pci_attach_device(NULL, PCI_SHARE | PCI_INIT_ALL | PCI_MASTER_ENABLE, iBrdIndex, &DevInfo);

/ISR function/
const struct sigevent* ISR(void * parameter, int id)
{
int s16RetVal = 0;
s16RetVal = ReadReg(); //reading the registers will happens here
return &SigInt;
}

What’s going on in ReadReg()? We don’t see the code related to that. Maybe the ISR is stuck in whatever ReadReg() does.

How do you know the hardware board is generating an interrupt?

As Nico mentioned you should consider switching back to interruptAttachEvent(). The reason for doing that is so you can use the debugger and see what’s happening when the ISR gets called.

Tim

In ReadReg(), i am just reading the FPGA register. Eventhough i had commented that function call( ReadReg() ), the ISR is not called.

Here i am using FPGA as a medium to communicate between software and hardware, When the hardware generates the interrupt FPGA is updated and it signals software.

I am compiling my code in " QNX® Momentics® Integrated Development Environment Version: 4.7.0 " as a MakeFile project, How can i use debugger in this IDE to get to know “how the ISR gets called.”

Still i haven’t found any solution for this issue, If any solutions for this issue let me know.

Manikanta

As per our need, PCI_INIT_ALL is sufficient , but I tried changing as per your suggestion for pci_attach_device() as mentioned above, but after attaching the device , driver gets unstoppable and giving undefined behaviour occurs(I made some prints in driver code,those are printing continuously ).

This Code is refelected as a porting of code from Linux and Xenomai. As of now this code is properly working on both, and generating the interrupts properly. But in case of Qnx i am facing this issue.(ISR is not called .)

Manikanta

Do you use a PCI device or a PCI express device ?

This is QNX 7 doc’s but there is noting really different between this at 6.5 which is what you are using. You can find the 6.5 equivalent doc’s online if you search for them.

qnx.com/developers/docs/7.0. … ching.html

I don’t know if your target machine has serial or ethernet connection to it. So you’ll need to read all the stuff at the link and other links it has depending on your communication method.

One thing for sure, you need qconn running on your target machine for the momentics suite to connect and debug.

Tim

Thanks to nico04 for your reply.

—>We are using PCI device