Skip navigation.
Home
The QNX Community Portal

View topic - IRQ not being detected

IRQ not being detected

Read-only archive of qnx.ddk (Writing device drivers for scanners, video card, optical mouse, etc) at inn.qnx.com

Re: Re: IRQ not being detected

Postby wasiul » Thu Jul 20, 2006 1:31 pm

Build a resource manager that does the following. Attach a simple
handler to every interrupt. In the interrupt handler, update a
count for each interrupt. When you read from your resource manager,
just return the counts.

Now you can go in and see if any interrupt is firing when you think 5
should be.

Thanks, did that and discovered the its not firing at all! Everything is
fine except getting this IRQ working. This works under linux when i boot to
linux, so what does QNX need to enable IRQ5 on a specific piece of
hardware. Do i need to add something else to the recource manager ive
written?
Thanks.
wasiul
 

Re: IRQ not being detected

Postby Mario Charest » Thu Jul 20, 2006 3:10 pm

"wasiul" <wasiul06@yahoo.com> wrote in message
news:e9nund$jek$1@inn.qnx.com...
And the IRQ5 has been assigned to your board ??
Please check it with 'pci -vvv' ...
--Armin


Ach, there might be the problem. Everything works fine except detecting
the IRQ. The card is a p/c104 type.

PC104 !!! Well unless it's PC104+ this is an ISA device not an PCI
device. If it's ISA pci -v will not see it.

The device could use ISA plug-and-play which I don't think is support in
QNX.

It's possible the IRQ must be assigned via some proprietary method.

No manufacturer, i think its house made, limited specs or anything
available to me except the linux driver.
I looked at 'pci -vvv' and dont realy make much sense of it, i didnt see
'Intterrupt line 5' just 11, b and 0. I tried doing something with
pci_attach_device() but i dont know the vendor or anything so how can i
attach it?
How do i assign the IRQ to the board?
Thanks!
Mario Charest
 

RE: Re: Re: IRQ not being detected

Postby maschoen » Thu Jul 20, 2006 3:48 pm

Now if you think about this for a minute, you now know that your interrupt handler is not being entered, nor any other on this interrupt. Assuming you've used the example code, and/or have seen interrupts on other IRQ's, then you know you've set things up with OS correctly. This only leaves the possibility that the IRQ is not firing. Presumably you're using the initalization code from the Linux driver. So what is left to explain things not working? Here are some thoughts.

1) Somehow IRQ is assigned wrong (this was discussed earlier)
2) QNX OS hardware initalization of IRQ's is different from Linux (Not likely)
3) Some other software in your system is disabling the IRQ
4) There is a blatant/subtle code difference that you haven't picked up on yet

Diagnosing this type of problem can be quite difficult. It's always nice if you have hardware access to the IRQ and can put a scope on it to confirm that it's really not firing. Sometimes there's access in front of the hardware's enabling circuit so you can see if the hardware fires, but the signal is not being passed through. There also might be a register you can read, telling you that the hardware thinks it has fired the IRQ.

I often find it helpful to replace the I/O instructions with versions that display to stderr what is happening, so that you can confirm the initalization. Of course this is not a good idea in an interrupt handler, but then you never get there anyway.

Desk check, desk check, desk check.

Sometimes when things are glum, it's good to recite this mantra.

"Hardware doesn't know which OS is running".

Good luck
maschoen
QNX Master
 
Posts: 2640
Joined: Wed Jun 25, 2003 5:18 pm

Re: IRQ not being detected

Postby Steinhoff » Thu Jul 20, 2006 3:50 pm

wasiul wrote:

Build a resource manager that does the following. Attach a simple
handler to every interrupt. In the interrupt handler, update a
count for each interrupt. When you read from your resource manager,
just return the counts.

Now you can go in and see if any interrupt is firing when you think 5
should be.



Thanks, did that and discovered the its not firing at all!
Everything is fine except getting this IRQ working. This works under

linux when i boot to linux, so what does QNX need to enable IRQ5 on a
specific piece of hardware. Do i need to add something else to the
recource manager ive written?


If your board is a plain PC/104 (not PCI or PC/104+) board then YOU have
to jumper the IRQ of the board or you have to set the IRQ by your driver!

You have also to check if an other device (serial/printer) is using the
IRQ 5. If it is so try to use a different IRQ (10,11,12 e.g)

And ... you must set the choosen IRQ as 'legazy ISA' in the BIOS setup!!


--Armin
Steinhoff
QNX Master
 
Posts: 279
Joined: Tue Sep 03, 2002 11:56 am

Re: Re: Re: IRQ not being detected

Postby kwschumm » Thu Jul 20, 2006 5:50 pm

There's also the possibility that it's firing once and is not getting
cleared properly so it hangs forever. As Mitchell said, put a scope on it so
you can see what the hardware is doing. I used an old motherboard once that
left the RTC IRQ8 high and unserviced right after boot. The interrupt had to
be cleared before it would work. This was not a commonly used interrupt so
it seems nobody ever noticed it before.
kwschumm
Senior Member
 
Posts: 306
Joined: Fri Sep 17, 2004 12:46 pm

Re: IRQ not being detected

Postby wasiul » Fri Jul 21, 2006 12:14 pm

If your board is a plain PC/104 (not PCI or PC/104+) board then YOU have
to jumper the IRQ of the board or you have to set the IRQ by your driver!
You have also to check if an other device (serial/printer) is using the
IRQ 5. If it is so try to use a different IRQ (10,11,12 e.g)
And ... you must set the choosen IRQ as 'legazy ISA' in the BIOS setup!!
--Armin

Board as far as i can tell is plain pc104. There is a jumper to select
IRQ5 or IRQ10, set to IRQ5 on the board. Set in the bios IRQ5 and 10 to
'legacy ISA' dont think anything else is using those irq's. the irq is
firing on the hardware(looked at it with a scope) so all thats missing is
how to detect it in qnx. Is there some sort of mapping i need to do?
Thanks.
wasiul
 

Re: IRQ not being detected-SOLVED

Postby wasiul » Fri Jul 21, 2006 1:50 pm

Well i finaly solved it!!!
At least i learned a lot.
Here is a rundown of what the problems were and solutions for others who
follow:

The first problem was i was not registering any interrupts because my
interrupt funciton was buggy. The best thing to do is use the example here:
http://www.qnx.com/developers/docs/6.3. ... PTHANDLING.
And modify it by changing the IRQ from the clock to what you need.

The second problem was that the recource manager was not picking the IRQ i
wanted from the hardware (IRQ 5). THe hardware worked because when i used
the example code from the link above and threw in there the code for my
hardware it was reading it correctly. So it had to be some issue with the
hardware not sending the IRQ.

Turned out that what i had was a P/C104, well that didnt mean much to me
before i started writing this so i ignored it. What i had to do was in the
BIOS change IRQ 5 to be for Legacy ISA and make sure nothing else was using
IRQ5. Thats when it started working!

I thank all of you that responded to my questions. There is no way i would
have figured this out if it wasnt for your help. THANK YOU VERY MUCH!!!

|My best regards,
wasiul
wasiul
 

RE: Re: IRQ not being detected-SOLVED

Postby maschoen » Fri Jul 21, 2006 2:58 pm

This does present an obvious question. If you needed to make a change to the BIOS, how was it working with Linux?
maschoen
QNX Master
 
Posts: 2640
Joined: Wed Jun 25, 2003 5:18 pm

Re: Re: IRQ not being detected-SOLVED

Postby wasiul » Tue Jul 25, 2006 11:01 am

This does present an obvious question. If you needed to make a change
to the BIOS, how was it working with Linux?


That i dont know and would like to find out. could there be something
setting that irq to ISA when the linux partition starts?
wasiul
 

IRQ is not Detecting

Postby HideAndSeek » Tue Jan 23, 2007 11:54 am

Dear gurus,
In my case also the same problem. The control is not moving into the ISR handler for USB connection. When i did "pci -v" in the terminal i got the IRQ as 5.

And please find the code below and suggest any changes so that the interrupt can be triggered and the control moves into the ISR handler.

Here IRQ is 5 and IO strating address of H/w is 01020h as given in Qnx terminal through pci -v command.


#define WALKER_NR_PORTS 16
#define IOBASE 0x1020
#define DMKPC (IOBASE+0x00)

void *int_thread (void *arg);
extern const struct sigevent *isr_handler (void *arg, int id);

#define IRQ5 5
int intrAttach = 0;
struct sigevent event;




int main(int argc, char *argv[]) {
// interupt handler
int iSimpleArg = 0;

ThreadCtl(_NTO_TCTL_IO, NULL);
mmap_device_io(WALKER_NR_PORTS, IOBASE);
pthread_create (NULL, NULL, int_thread, (void *)iSimpleArg);

for(int iLoop = 0; iLoop < 1000; iLoop++)
{
for(int iLoop = 0; iLoop < 1000; iLoop++)
// std::cout<<"\nIam out of Thread";
sleep(2);
}

return EXIT_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void* int_thread (void *arg)
{
std::cout<<"The arg val is :"<<(int)arg;
// enables the IO privilages
ThreadCtl (_NTO_TCTL_IO, NULL);

memset(&event,0,sizeof(event));
event.sigev_notify = SIGEV_INTR;
SIGEV_INTR_INIT(&event);

int errvalue;
int errno;

errno = 0;

// Attach interuupt.
intrAttach = InterruptAttach (IRQ5, isr_handler, &event, sizeof(event), 0);
if (intrAttach < 0)
{
errvalue = errno;
std::cout<< "The error generated was %d\n"<< errvalue ;
std::cout<<"That means: %s\n" <<strerror( errvalue );

}
while (1)
{
int iIntrWaitError = 0;
InterruptWait(0, NULL);

if (iIntrWaitError < 0)
{
//Error occured
}
else
{
if (SIGEV_INTR == event.sigev_notify)
{
//call the object of the class to filter the files.
std::cout<<"\n Interrupt detected.";
}
else
{
// continue this loop
}
}
// at this point, when InterruptWait unblocks,
// the ISR has returned a SIGEV_INTR, indicating
// that some form of work needs to be done.


// ...
// do the work
// ...
InterruptUnmask(IRQ5, intrAttach);
// if the isr_handler did an InterruptMask, then
// this thread should do an InterruptUnmask to
// allow interrupts from the hardware
}
InterruptDetach(intrAttach);

}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

const struct sigevent *isr_handler (void *arg, int id)
{
// probably here if iam making a mistake please correct me.
if(!(in16(DMKPC) & 0x1020))
{
return NULL;
}
// Here what is the next step i have to do.
InterruptMask(IRQ5, intrAttach);
return (&event);
}

I am much awaiting for the reply .......

-HideAndSeek.
HideAndSeek
New Member
 
Posts: 8
Joined: Thu Jan 04, 2007 5:39 am

Re: IRQ is not Detecting

Postby evanh » Tue Jan 23, 2007 7:32 pm

HideAndSeek wrote:
Dear gurus,
In my case also the same problem. The control is not moving into
the ISR handler for USB connection. When i did "pci -v" in
the terminal i got the IRQ as 5.


Before making any comment on the code provided, I'd like to ask if this really is a USB device?
evanh
QNX Master
 
Posts: 737
Joined: Sat Feb 01, 2003 8:04 am

re:IRQ not being detected

Postby tuyndie » Wed Apr 25, 2007 4:14 am

Dear all ,
i also write an interrupt handle for SH (not x86).
and i have also a problem the same ...
------------------------------------------------------
int main(int argc, char *argv[]) {
int pathID;
int errvalue;
char *name;
struct sigaction sa;

if (-1 == ThreadCtl(_NTO_TCTL_IO, 0))
{
if (verbose)
{
printf("%s: main: ThreadCtl failed\n", argv[0]);
}
return 0;
}
dev=(hcan2_dev_t *) malloc(sizeof(hcan2_dev_t ));
dev->regbase = (uintptr_t)MAP_FAILED;


// parse the command-line options
options(argc, argv);

// make sure the driver isn't already running
if ((name = malloc(sizeof(DEV_NAME) + 1)) == NULL)
{
fprintf(stderr, "%s: malloc failed\n", progname);
exit(-1);
}

// sprintf(name, "%s%d", RESMGR_NAME, adc_channel);
sprintf(name, "%s", RESMGR_NAME);
single_instance(name);

// allocate and initialize a dispatch structure for use by our main loop
dev->dpp = dispatch_create();
if (dev->dpp == NULL)
{
fprintf(stderr, "%s: couldn't dispatch_create: %s\n",
progname, strerror (errno));
exit(-1);
}

//
// Set up the resource manager attributes structure, we'll
// use this as a way of passing information to resmgr_attach().
// For now, we just use defaults.
//
memset(&rattr, 0, sizeof (rattr));
rattr.nparts_max = MAX_IOV_SIZE; // max ctp->iov[] size
rattr.msg_max_size = MAX_MSG_SIZE; // max size of a message

//
// Intialize the connect functions and I/O functions tables to
// their defaults and then override the defaults with the
// functions that we are providing.
//
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

// use our own: open, read, write, and devctl
connect_funcs.open = io_open;
io_funcs.read = io_read;
io_funcs.write = io_write;
io_funcs.devctl = io_devctl;

// set the mode to 0666 (R/W)
// Note leading 0 for octal -------v
iofunc_attr_init(&dev->hdr, S_IFCHR | 0666, NULL, NULL);

//
// Call resmgr_attach to register our prefix with the
// process manager, and also to let it know about our connect
// and I/O functions.
//
// On error, returns -1 and errno is set.
//
sprintf(name, "%s", DEV_NAME);
dev->id= resmgr_attach(dev->dpp, &rattr, name, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &dev->hdr);
if (dev->id == -1)
{
fprintf(stderr, "%s: couldn't attach pathname: %s\n",
progname, strerror(errno));
exit(1);
}
free(name);

/*allocate a context structure*/
dev->ctp = resmgr_context_alloc(dev->dpp);

//
// initialize the HW, map the registers and create driver structures
//
if (!hcan2_hw_init())
{
// HW init failed
fprintf(stderr, "%s: hcan_hw_init failed\n", progname);
return 0;
}

//Start up a thread that is dedicated to interrupt processing
pthread_create(NULL, NULL, int_thread, NULL);

/*Start the recource manager loop*/
while (!done) {
if (dev->ctp == resmgr_block(dev->ctp))
resmgr_handler(dev->ctp);
else if (errno != EFAULT)
atomic_set(&done, 1);
}

free(dev);

return 0;
}
-------------------------------------------------------------------

void *int_thread(void *arg)
{
int errvalue;
struct sigaction sa;

printf("In interrupt thread: Attaching the interrupt\n");
//Enable I/O privilege
ThreadCtl(_NTO_TCTL_IO, NULL);
memset(&dev->intr_event, 0, sizeof(&dev->intr_event));
// Initialize event structure
dev->intr_event.sigev_notify = SIGEV_INTR;
SIGEV_INTR_INIT(&dev->intr_event);


errno = EOK;
fprintf(stderr,"event =0x%04x \n",&dev->intr_event);
fprintf(stderr,"before interrupt dev->status=%d \n",&dev->status);
//Attach the ISR to IRQ
//interrupt attatch
dev->iid = InterruptAttach(dev->irq, (void*) _hcan2_irq_ser, &dev,0, 0);

if(dev->iid==-1)
{
printf( "Couldn't attach dev->irq %d\n", dev->irq );
exit(-1);
}

fprintf(stderr,"after interrupt dev->status=%d \n",&dev->status);

errvalue = errno;
printf( "The error generated was %d\n", errvalue );
printf( "That means: %s\n", strerror( errvalue ) );

printf("wait\n");

while(!(dev->status & HCAN_STATUS_DONE))
{
InterruptWait(0, NULL);
printf("received interrupt \n");
}
InterruptUnmask(dev->irq,dev->iid);
InterruptDetach(dev->iid);


}
--------------------------------------------------------------

const struct sigevent *
_hcan2_irq_ser(void *arg, int iid)
{
hcan2_dev_t *dev=(hcan2_dev_t *)arg;
struct sigevent *event = NULL;
int icntr;
uint16_t whatReg = 0;


event = &dev->intr_event;

InterruptMask(dev->irq,dev->iid);
return (event);
}
--------------------------------------------------------------
when i run . the terminal announce like as:
"out of interrupt event!"
i don't know why?
please help me
thanks,
tuyndie
tuyndie
Active Member
 
Posts: 36
Joined: Mon Aug 07, 2006 3:39 am

Previous

Return to qnx.ddk

Who is online

Users browsing this forum: No registered users and 1 guest

cron