IRQ not being detected

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

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 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;



}

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);

}



}

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);

}



}








\

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);

}



}

Hi,

please try the example in the System Architecture documentation at
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


“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);

}



}











\

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

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

Having a printf in an interrupt handler is an excellent way to see if
the interrupt is working, at least the first time. :wink: 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” <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. > :wink: > 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.

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.

\

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!

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” <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!

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

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

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.