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

IRQ not being detected

Postby wasiul » Fri Jul 14, 2006 11:43 am

Im writing a recource manager to communicate with a motor control. I need to
detect when IRQ5 fires to read in data from the board.
I have two problems:
1) I only read 0 from the register i want (occasionaly 0x100) when i read it
not waiting for the interrupt that signals that data is ready, i can write
to the register fine, but cant read anything sensible. I know i can write
because when i write the robot moves accordingly.

2)i set up an interrupt handler to monitor IRQ5 but the interrupt handler
never does anything just waits in the InterruptWait(NULL,NULL); part. the
hardware is starts at 0x320.

This is a ported driver from linux, interrupts work fine in linux, not
here:( ive tried everything for 2 days and nothing:( anyone have any ideas?

here is my code:
--------------

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define DPCMK1 (IOBASE+0x00)

#define DATA_IGNORE 0xFFFF



main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*setup Hardware I/O, need to do only once*/

ThreadCtl(_NTO_TCTL_IO, NULL);

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

printf("In interrupt thread: Attaching the interrupt\n");



/*Enable I/O privilege*/

ThreadCtl(_NTO_TCTL_IO, NULL);



/*Attach the ISR to IRQ*/

InterruptAttach(5, isr_handler, NULL, 0, 0);



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL);



}



}





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

/*This is the ISR*/

{

/*PROBLEM: NEVER ENTERS THIS FUNCTION*/



/*Look at the hardware to see if it caused the interrupt, if not
return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE;

}



/*This is done when the robot sends an interrupt that its ready
to recieve data*/

if(flag == 1)

{

dmkpc = in16(DMKPC);

flag--;

}



/*aknowlege we processed the interrupt*/

out16(DATA_IGNORE, IRQACK);



/*Return a pointer to an event structure (preinitialized by
main) that

* contains SIGEV_INTR as its notification type. This causes the
InterruptWait

* in "int_thread" to unblock.*/

return (struct sigevent *)1;



}



----------

Thanks!
wasiul
 

Re: IRQ not being detected

Postby Steinhoff » Fri Jul 14, 2006 12:32 pm

wasiul wrote:
Im writing a recource manager to communicate with a motor control. I need to
detect when IRQ5 fires to read in data from the board.
I have two problems:
1) I only read 0 from the register i want (occasionaly 0x100) when i read it
not waiting for the interrupt that signals that data is ready, i can write
to the register fine, but cant read anything sensible. I know i can write
because when i write the robot moves accordingly.

2)i set up an interrupt handler to monitor IRQ5 but the interrupt handler
never does anything just waits in the InterruptWait(NULL,NULL); part. the
hardware is starts at 0x320.

That looks very strange: return (struct sigevent *)1;

YXou have to retun a real interrupt event.

--Armin


This is a ported driver from linux, interrupts work fine in linux, not
here:( ive tried everything for 2 days and nothing:( anyone have any ideas?

here is my code:
--------------

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define DPCMK1 (IOBASE+0x00)

#define DATA_IGNORE 0xFFFF



main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*setup Hardware I/O, need to do only once*/

ThreadCtl(_NTO_TCTL_IO, NULL);

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

printf("In interrupt thread: Attaching the interrupt\n");



/*Enable I/O privilege*/

ThreadCtl(_NTO_TCTL_IO, NULL);



/*Attach the ISR to IRQ*/

InterruptAttach(5, isr_handler, NULL, 0, 0);



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL);



}



}





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

/*This is the ISR*/

{

/*PROBLEM: NEVER ENTERS THIS FUNCTION*/



/*Look at the hardware to see if it caused the interrupt, if not
return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE;

}



/*This is done when the robot sends an interrupt that its ready
to recieve data*/

if(flag == 1)

{

dmkpc = in16(DMKPC);

flag--;

}



/*aknowlege we processed the interrupt*/

out16(DATA_IGNORE, IRQACK);



/*Return a pointer to an event structure (preinitialized by
main) that

* contains SIGEV_INTR as its notification type. This causes the
InterruptWait

* in "int_thread" to unblock.*/

return (struct sigevent *)1;



}



----------

Thanks!

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

Re: IRQ not being detected

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

That looks very strange: return (struct sigevent *)1;
YXou have to retun a real interrupt event.
--Armin

The only other thingit could be is: return arg;
as event isnt global, or should it be?
Im using the example given in "Writing an Interrupt handler"
they have return &event; which is supposedly declared in main... but how do
you declare it?
i dont understand this:
// return a pointer to an event structure (preinitialized
// by main) that contains SIGEV_INTR as its notification type.
// This causes the InterruptWait in "int_thread" to unblock.



const struct sigevent * isr_handler(void *arg, int id)
/*This is the ISR*/

{

/*PROBLEM: NEVER ENTERS THIS FUNCTION*/



/*Look at the hardware to see if it caused the interrupt, if
not return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE;

}



/*This is done when the robot sends an interrupt that its
ready to recieve data*/

if(flag == 1)

{

dmkpc = in16(DMKPC);

flag--;

}



/*aknowlege we processed the interrupt*/

out16(DATA_IGNORE, IRQACK);



/*Return a pointer to an event structure (preinitialized by
main) that

* contains SIGEV_INTR as its notification type. This causes
the InterruptWait

* in "int_thread" to unblock.*/

return arg;



}
wasiul
 

Re: IRQ not being detected

Postby Steinhoff » Fri Jul 14, 2006 2:36 pm

wasiul wrote:
That looks very strange: return (struct sigevent *)1;
YXou have to retun a real interrupt event.
--Armin


The only other thingit could be is: return arg;
as event isnt global, or should it be?
Im using the example given in "Writing an Interrupt handler"
they have return &event; which is supposedly declared in main... but how do
you declare it?
i dont understand this:
// return a pointer to an event structure (preinitialized
// by main) that contains SIGEV_INTR as its notification type.
// This causes the InterruptWait in "int_thread" to unblock.

You have to initialize a global event, like

struct sigevent IRQevent; // defined as module global

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


And your handler must return

return (&IRQevent);

That's all ...

--Armin






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

/*This is the ISR*/

{

/*PROBLEM: NEVER ENTERS THIS FUNCTION*/



/*Look at the hardware to see if it caused the interrupt, if
not return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE;

}



/*This is done when the robot sends an interrupt that its
ready to recieve data*/

if(flag == 1)

{

dmkpc = in16(DMKPC);

flag--;

}



/*aknowlege we processed the interrupt*/

out16(DATA_IGNORE, IRQACK);



/*Return a pointer to an event structure (preinitialized by
main) that

* contains SIGEV_INTR as its notification type. This causes
the InterruptWait

* in "int_thread" to unblock.*/

return arg;



}


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

Re: IRQ not being detected

Postby wasiul » Tue Jul 18, 2006 11:46 am

You have to initialize a global event, like

struct sigevent IRQevent; // defined as module global

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

And your handler must return

return (&IRQevent);

That's all ...
--Armin


Still no luck...
I added the global even, but the InterruptWait(NULL, NULL) still never
returns. Is my initialization in main wrong? In main i initialize the
Hardware and do:
pthread_create(NULL, NULL, &int_thread, NULL);
and then loop forever the 'dispatch_handler(ctp)' in order to recieve
devctl and read messages passed to the recource manager.

Thanks!

here is the source:


/*Define ports and variables for hardware I/O*/

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define SMKPC (IOBASE+0x02)

#define IRQACK (IOBASE+0x04)

#define DATA_IGNORE 0xFFFF

#define BUSY_RETRY 50



#define IRQ5 5
/*interrupt type*/



#define DEVNAME "/dev/walker0" /*The
device name*/



struct sigevent IRQevent; /*IRQ interrupt
event*/





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

int id;



printf("In interrupt thread: Attaching the interrupt\n");

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0){

fprintf(stderr, "Unable to get thread IO permission\n");

}



/*INIT IRQ*/

memset(&IRQevent, 0, sizeof(IRQevent));

IRQevent.sigev_notify = SIGEV_INTR;

SIGEV_INTR_INIT(&IRQevent);



/*Attach the ISR to IRQ*/

id = InterruptAttach(IRQ5, isr_handler, &IRQevent,
sizeof(IRQevent), 0) ;


if(id == -1)

{

fprintf(stderr, "InterruptAttach failed!\n");

exit(-1);

}



out16(0xFFFF, 0x324); /*enable the interrupt in the
hardware*/



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL); /*NEVER
RETURNS.*/



/*DO I HAVE TO DO ANYTHING HERE or is it all handled
in the isr_handler??*/



InterruptDetach(id);

}



}





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

/*This is the ISR*/

{

/*THIS NEVER PRINTS*/

printf("In istr_handler!!!!!!!!!!!!!\n");



/*Look at the hardware to see if it caused the interrupt, if not
return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE; }



/*Hardware I/O*/

dmkpc = in16(DMKPC);

out16(DATA_IGNORE, IRQACK);



return (&IRQevent);

}







main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*Hardware Initialization, need to do only once*/

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0)

{

fprintf(stderr, "Unable to get thread IO
permission\n");

return EXIT_FAILURE;

}

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);

if(iobase != IOBASE)

{

fprintf(stderr, "mmap_device_io give: %x, returned
%x (they should be the same but arent)\n", IOBASE, iobase);

return EXIT_FAILURE;

}

/*End Hardware init*/



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, &int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}
wasiul
 

Re: IRQ not being detected

Postby mrossi » Tue Jul 18, 2006 1:47 pm

Hi,

please try this instruction to enable the interrupt:

out16(0x324,0xFFFF);

Regards,
Maurizio Rossi


"wasiul" <wasiul06@yahoo.com> ha scritto nel messaggio
news:e9ihii$lrt$1@inn.qnx.com...

You have to initialize a global event, like

struct sigevent IRQevent; // defined as module global

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

And your handler must return

return (&IRQevent);

That's all ...
--Armin


Still no luck...
I added the global even, but the InterruptWait(NULL, NULL) still never
returns. Is my initialization in main wrong? In main i initialize the
Hardware and do:
pthread_create(NULL, NULL, &int_thread, NULL);
and then loop forever the 'dispatch_handler(ctp)' in order to recieve
devctl and read messages passed to the recource manager.

Thanks!

here is the source:


/*Define ports and variables for hardware I/O*/

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define SMKPC (IOBASE+0x02)

#define IRQACK (IOBASE+0x04)

#define DATA_IGNORE 0xFFFF

#define BUSY_RETRY 50



#define IRQ5 5 /*interrupt type*/



#define DEVNAME "/dev/walker0" /*The
device name*/



struct sigevent IRQevent; /*IRQ interrupt
event*/





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

int id;



printf("In interrupt thread: Attaching the interrupt\n");

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0){

fprintf(stderr, "Unable to get thread IO permission\n");

}



/*INIT IRQ*/

memset(&IRQevent, 0, sizeof(IRQevent));

IRQevent.sigev_notify = SIGEV_INTR;

SIGEV_INTR_INIT(&IRQevent);



/*Attach the ISR to IRQ*/

id = InterruptAttach(IRQ5, isr_handler, &IRQevent,
sizeof(IRQevent), 0) ;


if(id == -1)

{

fprintf(stderr, "InterruptAttach failed!\n");

exit(-1);

}



out16(0xFFFF, 0x324); /*enable the interrupt in the
hardware*/



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL); /*NEVER
RETURNS.*/



/*DO I HAVE TO DO ANYTHING HERE or is it all
handled in the isr_handler??*/



InterruptDetach(id);

}



}





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

/*This is the ISR*/

{

/*THIS NEVER PRINTS*/

printf("In istr_handler!!!!!!!!!!!!!\n");



/*Look at the hardware to see if it caused the interrupt, if
not return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE; }



/*Hardware I/O*/

dmkpc = in16(DMKPC);

out16(DATA_IGNORE, IRQACK);



return (&IRQevent);

}







main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*Hardware Initialization, need to do only once*/

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0)

{

fprintf(stderr, "Unable to get thread IO
permission\n");

return EXIT_FAILURE;

}

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);

if(iobase != IOBASE)

{

fprintf(stderr, "mmap_device_io give: %x, returned
%x (they should be the same but arent)\n", IOBASE, iobase);

return EXIT_FAILURE;

}

/*End Hardware init*/



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, &int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}











mrossi
Active Member
 
Posts: 20
Joined: Thu Aug 29, 2002 11:58 am

Re: IRQ not being detected

Postby wasiul » Wed Jul 19, 2006 11:05 am

please try this instruction to enable the interrupt:
out16(0x324,0xFFFF);
Maurizio Rossi

Well that was a big error i didnt catch! Thanks, unfortunatly still no
success.
The interrupt works fine in linux (dual boot linux qnx) so its the same
hardware and IRQ's right? is there anything wrong with my code?
What can i connect to check if my code can detect IRQ5 or some other IRQ?
just to narrow down where the problem is occuring? Thanks!


/*Define ports and variables for hardware I/O*/

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define SMKPC (IOBASE+0x02)

#define IRQACK (IOBASE+0x04)

#define DATA_IGNORE 0xFFFF

#define BUSY_RETRY 50



#define IRQ5 5
/*interrupt type*/



#define DEVNAME "/dev/walker0" /*The
device name*/



struct sigevent IRQevent; /*IRQ interrupt
event*/





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

int id;



printf("In interrupt thread: Attaching the interrupt\n");

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0){

fprintf(stderr, "Unable to get thread IO permission\n");

}



/*INIT IRQ*/

memset(&IRQevent, 0, sizeof(IRQevent));

IRQevent.sigev_notify = SIGEV_INTR;

SIGEV_INTR_INIT(&IRQevent);



/*Attach the ISR to IRQ*/

id = InterruptAttach(IRQ5, isr_handler, &IRQevent,
sizeof(IRQevent), 0) ;


if(id == -1)

{

fprintf(stderr, "InterruptAttach failed!\n");

exit(-1);

}



out16(0x324, 0xFFFF); /*enable the interrupt in the
hardware*/



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL); /*NEVER
RETURNS.*/



/*DO I HAVE TO DO ANYTHING HERE or is it all handled
in the isr_handler??*/



InterruptDetach(id);

}



}





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

/*This is the ISR*/

{

/*THIS NEVER PRINTS*/

printf("In istr_handler!!!!!!!!!!!!!\n");



/*Look at the hardware to see if it caused the interrupt, if not
return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE; }



/*Hardware I/O*/

dmkpc = in16(DMKPC);

out16(IRQACK, DATA_IGNORE);



return (&IRQevent);

}







main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*Hardware Initialization, need to do only once*/

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0)

{

fprintf(stderr, "Unable to get thread IO
permission\n");

return EXIT_FAILURE;

}

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);

if(iobase != IOBASE)

{

fprintf(stderr, "mmap_device_io give: %x, returned
%x (they should be the same but arent)\n", IOBASE, iobase);

return EXIT_FAILURE;

}

/*End Hardware init*/



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, &int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}
wasiul
 

Re: IRQ not being detected

Postby mrossi » Wed Jul 19, 2006 12:12 pm

Hi,

please try the example in the System Architecture documentation at
http://www.qnx.com/developers/docs/6.3. ... PTHANDLING.
After confirming the example is working modify it as required for your
hardware.

P.S.
Do not use printf() in an interrupt handler function!

Regards,
Maurizio Rossi


"wasiul" <wasiul06@yahoo.com> ha scritto nel messaggio
news:e9l3ge$i3i$1@inn.qnx.com...
please try this instruction to enable the interrupt:
out16(0x324,0xFFFF);
Maurizio Rossi

Well that was a big error i didnt catch! Thanks, unfortunatly still no
success.
The interrupt works fine in linux (dual boot linux qnx) so its the same
hardware and IRQ's right? is there anything wrong with my code?
What can i connect to check if my code can detect IRQ5 or some other IRQ?
just to narrow down where the problem is occuring? Thanks!


/*Define ports and variables for hardware I/O*/

#define WALKER_NR_PORTS 16

#define IOBASE 0x320

#define DMKPC (IOBASE+0x00)

#define SMKPC (IOBASE+0x02)

#define IRQACK (IOBASE+0x04)

#define DATA_IGNORE 0xFFFF

#define BUSY_RETRY 50



#define IRQ5 5
/*interrupt type*/



#define DEVNAME "/dev/walker0" /*The
device name*/



struct sigevent IRQevent; /*IRQ interrupt
event*/





void *int_thread(void *arg)

/*This thread is dedicated to handling and managing interrupts*/

{

int id;



printf("In interrupt thread: Attaching the interrupt\n");

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0){

fprintf(stderr, "Unable to get thread IO permission\n");

}



/*INIT IRQ*/

memset(&IRQevent, 0, sizeof(IRQevent));

IRQevent.sigev_notify = SIGEV_INTR;

SIGEV_INTR_INIT(&IRQevent);



/*Attach the ISR to IRQ*/

id = InterruptAttach(IRQ5, isr_handler, &IRQevent,
sizeof(IRQevent), 0) ;


if(id == -1)

{

fprintf(stderr, "InterruptAttach failed!\n");

exit(-1);

}



out16(0x324, 0xFFFF); /*enable the interrupt in the
hardware*/



/*Now service the hardware when the ISR says to*/

while(1)

{

InterruptWait(NULL, NULL); /*NEVER
RETURNS.*/



/*DO I HAVE TO DO ANYTHING HERE or is it all
handled
in the isr_handler??*/



InterruptDetach(id);

}



}





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

/*This is the ISR*/

{

/*THIS NEVER PRINTS*/

printf("In istr_handler!!!!!!!!!!!!!\n");



/*Look at the hardware to see if it caused the interrupt, if
not
return NULL*/

if(!(in16(SMKPC) & 0x000e))

{

return SIGEV_NONE; }



/*Hardware I/O*/

dmkpc = in16(DMKPC);

out16(IRQACK, DATA_IGNORE);



return (&IRQevent);

}







main (int argc, char **argv)

{

resmgr_attr_t resmgr_attr;

dispatch_t *dpp;

dispatch_context_t *ctp;

int id;



/*Initialize dispatch interface*/

if((dpp = dispatch_create()) == NULL)

{

fprintf(stderr, "%s: Unable to allocate dispatch
handle.\n", argv[0]);

return EXIT_FAILURE;

}



/*Initialize recource manager attributes*/

memset(&resmgr_attr, 0, sizeof resmgr_attr);

resmgr_attr.nparts_max = 1;

resmgr_attr.msg_max_size = 2048;



/*Initialize function for handling messages*/

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

io_funcs.read = io_read;

io_funcs.devctl = io_devctl; /* For handling _IO_DEVCTL, sent
by devctl() */



/*initialize attribute structure used by the device*/

iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

attr.nbytes = strlen(buffer) +1;



/*attach the device name*/

if((id = resmgr_attach(dpp, &resmgr_attr, DEVNAME, _FTYPE_ANY,
0, &connect_funcs, &io_funcs, &attr)) == -1)

{

fprintf(stderr, "%s: Unable to attach name. \n",
argv[0]);

return EXIT_FAILURE;

}



/*allocate a context structure*/

ctp = dispatch_context_alloc(dpp);



/*Hardware Initialization, need to do only once*/

if(ThreadCtl(_NTO_TCTL_IO, NULL) != 0)

{

fprintf(stderr, "Unable to get thread IO
permission\n");

return EXIT_FAILURE;

}

iobase = mmap_device_io(WALKER_NR_PORTS, IOBASE);

if(iobase != IOBASE)

{

fprintf(stderr, "mmap_device_io give: %x, returned
%x (they should be the same but arent)\n", IOBASE, iobase);

return EXIT_FAILURE;

}

/*End Hardware init*/



/*Start up a thread that is dedicated to interrupt processing*/

pthread_create(NULL, NULL, &int_thread, NULL);



/*Start the recource manager loop*/

while(1)

{

if((ctp = dispatch_block(ctp)) == NULL)

{

fprintf(stderr, "block error\n");

return EXIT_FAILURE;

}

dispatch_handler(ctp);

}



}














mrossi
Active Member
 
Posts: 20
Joined: Thu Aug 29, 2002 11:58 am

Re: IRQ not being detected

Postby wasiul » Wed Jul 19, 2006 1:21 pm

http://www.qnx.com/developers/docs/6.3. ... PTHANDLING. After confirming the example is working modify it as required for yourhardware.>> P.S.> Do not use printf() in an interrupt handler function!> Regards,> Maurizio Rossi Tried and modified the example, works with the clock interrupt andkeyboard and other IRQ's but it still doesnt detect IRQ5. Im guessingthere has to be something strange going on with the hardware in QNX, couldthe IRQ's be different under linux and QNX?Booting into linux the IRQ from the hardware is #5, and everything worksfine, under QNX no such luck. Any way to see what the IRQ's are assigned to? it might be that they arereasigned as im loading the QNX from an NFS server and it does some "biosmagic".Thanks for your help so far!! Best board ever!~wasiul
wasiul
 

Re: IRQ not being detected

Postby wasiul » Wed Jul 19, 2006 1:23 pm

http://www.qnx.com/developers/docs/6.3. ... PTHANDLING.
After confirming the example is working modify it as required for your
hardware.>
P.S.> Do not use printf() in an interrupt handler function!
Regards,
Maurizio Rossi

(above post got newlines cut off for some reason)

Tried and modified the example, works with the clock interrupt andkeyboard
and other IRQ's but it still doesnt detect IRQ5. Im guessing there has to
be something strange going on with the hardware in QNX, could the IRQ's be
different under linux and QNX? Booting into linux the IRQ from the hardware
is #5, and everything works fine, under QNX no such luck.
Any way to see what the IRQ's are assigned to? it might be that they
arereasigned as im loading the QNX from an NFS server and it does some
"biosmagic".Thanks for your help so far!! Best board ever!~wasiul
wasiul
 

Re: IRQ not being detected

Postby Steinhoff » Wed Jul 19, 2006 2:17 pm

wasiul wrote:
http://www.qnx.com/developers/docs/6.3.0SP2/neutrino/sys_arch/kernel.html#INTERRUPTHANDLING.
After confirming the example is working modify it as required for your
hardware.

P.S.> Do not use printf() in an interrupt handler function!
Regards,
Maurizio Rossi


(above post got newlines cut off for some reason)

Tried and modified the example, works with the clock interrupt andkeyboard
and other IRQ's but it still doesnt detect IRQ5.

And the IRQ5 has been assigned to your board ??

Please check it with 'pci -vvv' ...

--Armin



Im guessing there has to
be something strange going on with the hardware in QNX, could the IRQ's be
different under linux and QNX? Booting into linux the IRQ from the hardware
is #5, and everything works fine, under QNX no such luck.
Any way to see what the IRQ's are assigned to? it might be that they
arereasigned as im loading the QNX from an NFS server and it does some
"biosmagic".Thanks for your help so far!! Best board ever!~wasiul

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

RE: Re: IRQ not being detected

Postby maschoen » Wed Jul 19, 2006 4:29 pm

Having a printf in an interrupt handler is an excellent way to see if the interrupt is working, at least the first time. ;-) It usually will crash your system. When I ran into this type of problem in QNX 4, there was an easy way to investigate. Here is an outline.

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.
maschoen
QNX Master
 
Posts: 2644
Joined: Wed Jun 25, 2003 5:18 pm

Re: Re: IRQ not being detected

Postby Mario Charest » Wed Jul 19, 2006 8:31 pm

"maschoen" <maschoen@pobox-dot-com.no-spam.invalid> wrote in message
news:e9lrqs$4nf$1@inn.qnx.com...
Having a printf in an interrupt handler is an excellent way to see if
the interrupt is working, at least the first time. ;-) It usually
will crash your system. When I ran into this type of problem in QNX
4, there was an easy way to investigate. Here is an outline.

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.


Latest sysmon (0.347) will give you that information

sysmon m=intr

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


>
Mario Charest
 

Re: Re: IRQ not being detected

Postby Mario Charest » Wed Jul 19, 2006 8:33 pm

..

Latest sysmon (0.347) will give you that information

sysmon m=intr

Woops sorry, ignore that, was thinking QNX4

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




Mario Charest
 

Re: IRQ not being detected

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

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. 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!
wasiul
 

Next

Return to qnx.ddk

Who is online

Users browsing this forum: No registered users and 1 guest

cron