IRQ not being detected

bridged with qnx.ddk
wasiul

Re: Re: IRQ not being detected

Post by 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.

Mario Charest

Re: IRQ not being detected

Post by 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!

Armin Steinhoff

Re: IRQ not being detected

Post by Armin 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

maschoen

RE: Re: Re: IRQ not being detected

Post by maschoen » Thu Jul 20, 2006 3:57 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

Ken Schumm

Re: Re: Re: IRQ not being detected

Post by Ken Schumm » 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.

wasiul

Re: IRQ not being detected

Post by 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

Post by 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

maschoen

RE: Re: IRQ not being detected-SOLVED

Post by maschoen » Fri Jul 21, 2006 3:57 pm

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

wasiul

Re: Re: IRQ not being detected-SOLVED

Post by 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?

HideAndSeek

IRQ is not Detecting

Post by HideAndSeek » Tue Jan 23, 2007 12:00 pm

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.

Evan Hillas

Re: IRQ is not Detecting

Post by Evan Hillas » 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?

tuyndie

re:IRQ not being detected

Post by tuyndie » Wed Apr 25, 2007 5:55 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

Post Reply

Return to “qnx.ddk”