Trying to attach to timer interrupt -- ??

I’ve been trying to use InterruptAttachEvent to attach to
INT 0 (the timer interrupt). Thus far, attempts to do this
have been unsuccessful. I’ve succeeded using InterruptAttach,
but I’m missing something in my InterruptAttachEvent code;
probably just one call or some initialization. In any case,
here’s my sample code. If someone spots the problem,
I’d appreciate knowning what I’m doing wrong.
Thanks,
Randy Hyde

p.s., the code below, on a PC, prints IRQ id = 9,
then “Calling Interrupt Wait”
and then nothing else happens.


void *
timerThread ( void( arg )
{
int IRQtimer_id;
int timer;

ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT( &IRQevent );
IRQtimer_id =
InterruptAttachEvent
(
0,
&IRQevent,
0
);

printf( “IRQ id=%d\n”, IRQtimer_id );

if ( IRQtimer_id == -1 )
{
printf
(
“timerThread: Unable to attach to interrupt (irq %u): %s\n”,
pitInt_c,
strerror( errno )
);
exit( EXIT_FAILURE );
}


// wait here forever, handling messages

timer = 0;
for(ever)
{
printf( “Calling Interrupt Wait\n” );
InterruptWait( 0, NULL );
printf( “Calling InterruptUnmask\n” );
InterruptUnmask( pitInt_c, IRQtimer_id );
++timer;
if( timer >= 1 )
{
printf( “Timer interrupt 10,000\n” );
timer = 0;
}
}
}

Hi Randy,

In article <b20p3j$hqj$1@inn.qnx.com>, randall.nospam.hyde@ustraffic.net says…

Subject: Trying to attach to timer interrupt – ??
From: “Randall Hyde” <> randall.nospam.hyde@ustraffic.net
Newsgroups: comp.os.qnx

I’ve been trying to use InterruptAttachEvent to attach to
INT 0 (the timer interrupt). Thus far, attempts to do this
have been unsuccessful. I’ve succeeded using InterruptAttach,
but I’m missing something in my InterruptAttachEvent code;
probably just one call or some initialization. In any case,
here’s my sample code. If someone spots the problem,
I’d appreciate knowning what I’m doing wrong.
Thanks,
Randy Hyde

p.s., the code below, on a PC, prints IRQ id = 9,
then “Calling Interrupt Wait”
and then nothing else happens.



void *
timerThread ( void( arg )

something wrong with brackets here…

{
int IRQtimer_id;
int timer;

ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT( &IRQevent );

is IRQevent a global structure?


IRQtimer_id =
InterruptAttachEvent
(
0,
&IRQevent,
0
);

printf( “IRQ id=%d\n”, IRQtimer_id );

if ( IRQtimer_id == -1 )
{
printf
(
“timerThread: Unable to attach to interrupt (irq %u): %s\n”,
pitInt_c,
strerror( errno )
);
exit( EXIT_FAILURE );
}



// wait here forever, handling messages

timer = 0;
for(ever)
{
printf( “Calling Interrupt Wait\n” );
InterruptWait( 0, NULL );
printf( “Calling InterruptUnmask\n” );
InterruptUnmask( pitInt_c, IRQtimer_id );

You use 0 in InterruptAttachEvent(), but pitInt_c here… it’s bad thing, IMO

++timer;
if( timer >= 1 )
{
printf( “Timer interrupt 10,000\n” );
timer = 0;
}
}
}

Are you sure you had written event handler which is fast enough? for 1 miliseconds rate events :slight_smile:
Those printf() eat much more time… I do not think INT 0 is a good interrupt for such programming,
because this interrupt is used by kernel for sheduling and internal timers. I believe this is your
problem. I can’t catch why do you try to do this in such way? What’s the main purpose of this
handler? Why you don’t use timers? If you need hardware generated events not so fast, you could use
RTC interrupt…

Best regards,
Eduard.

“Eduard” <ed1k@humber.bay> wrote in message
news:MPG.18addadebd962e75989685@inn.qnx.com

Hi Randy,
void *
timerThread ( void( arg )

something wrong with brackets here…

Just a cut and paste problem,
void * was defined at pvoid_t and I hand-typed it
to avoid having to explain it. Obviously, not a good idea
since I screwed up the hand typing … :slight_smile:

{
int IRQtimer_id;
int timer;

ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT( &IRQevent );

is IRQevent a global structure?

Yes.
Pertinent stuff that’s missing:

typedef void* pvoid_t;
#define ever ;;



IRQtimer_id =
InterruptAttachEvent
(
0,
&IRQevent,
0
);

printf( “IRQ id=%d\n”, IRQtimer_id );

if ( IRQtimer_id == -1 )
{
printf
(
“timerThread: Unable to attach to interrupt (irq %u): %s\n”,
pitInt_c,
strerror( errno )
);
exit( EXIT_FAILURE );
}


// wait here forever, handling messages

timer = 0;
for(ever)
{
printf( “Calling Interrupt Wait\n” );
InterruptWait( 0, NULL );
printf( “Calling InterruptUnmask\n” );
InterruptUnmask( pitInt_c, IRQtimer_id );

You use 0 in InterruptAttachEvent(), but pitInt_c here… it’s bad thing,
IMO

++timer;
if( timer >= 1 )
{
printf( “Timer interrupt 10,000\n” );
timer = 0;
}
}
}

Are you sure you had written event handler which is fast enough? for 1
miliseconds rate events > :slight_smile:
Those printf() eat much more time… I do not think INT 0 is a good
interrupt for such programming,
because this interrupt is used by kernel for sheduling and internal
timers. I believe this is your
problem. I can’t catch why do you try to do this in such way? What’s the
main purpose of this
handler? Why you don’t use timers? If you need hardware generated events
not so fast, you could use
RTC interrupt…

Best regards,
Eduard.

“Eduard” <ed1k@humber.bay> wrote in message
news:MPG.18addadebd962e75989685@inn.qnx.com

Hi Randy,

void *
timerThread ( void( arg )

something wrong with brackets here…

Yeah, it used to be pvoid_t instead of void*.
I tried replacing the stuff so I wouldn’t have to
explain it all. Obviously that was a mistake.


{
int IRQtimer_id;
int timer;

ThreadCtl( _NTO_TCTL_IO, 0 );
SIGEV_INTR_INIT( &IRQevent );

is IRQevent a global structure?

Yes, pertinent declarations:

typedef void* pvoid_t;
#define ever ;;


//! pitInt_c - Interrupt # for the timer interrupt.

#define pitInt_c 0 //!< PIT interrupt for 8254 timer #0






IRQtimer_id =
InterruptAttachEvent
(
0,
&IRQevent,
0
);

printf( “IRQ id=%d\n”, IRQtimer_id );

if ( IRQtimer_id == -1 )
{
printf
(
“timerThread: Unable to attach to interrupt (irq %u): %s\n”,
pitInt_c,
strerror( errno )
);
exit( EXIT_FAILURE );
}


// wait here forever, handling messages

timer = 0;
for(ever)
{
printf( “Calling Interrupt Wait\n” );
InterruptWait( 0, NULL );
printf( “Calling InterruptUnmask\n” );
InterruptUnmask( pitInt_c, IRQtimer_id );

You use 0 in InterruptAttachEvent(), but pitInt_c here… it’s bad thing,
IMO

The bad thing is that I missed this instance when hand replacing them
by zero for the post. :slight_smile:


++timer;
if( timer >= 1 )
{
printf( “Timer interrupt 10,000\n” );
timer = 0;
}
}
}

Are you sure you had written event handler which is fast enough? for 1
miliseconds rate events > :slight_smile:
Those printf() eat much more time… I do not think INT 0 is a good
interrupt for such programming,
because this interrupt is used by kernel for sheduling and internal
timers. I believe this is your
problem. I can’t catch why do you try to do this in such way? What’s the
main purpose of this
handler? Why you don’t use timers? If you need hardware generated events
not so fast, you could use
RTC interrupt…

I don’t need a timer interrupt at all.
What I need is a working template of an ISR that I can test on a PC before
moving it to the embedded system. Since the INT 0 interrupt is common on
both (and, in fact, I’ve gotten INT 0 to work fine on the embedded platform
in this manner), I figured it would be a good test of the basic ISR
structure
before moving on. As for race conditions and timing in the thread, as you
can
infer from the code, originally I had it waiting about 10 seconds between
messages
and then dropped it down to one second, and then once per loop when there
was no output. It, literally, never gets pass the InterruptWait.
So something else is going wrong here.
Randy Hyde

Now I am confused.
The following code works fine.
Maybe I missed a volatile or something somewhere?
Is there a problem with the original code because I used
a thread?

Hmmm…
Randy Hyde

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <errno.h>
#include <sys/neutrino.h>

typedef void* pvoid_t;
#define ever ;;

static struct sigevent event;
volatile int timer;


const struct sigevent *
MyIRQ(void *area, int id)
{
++timer;
return &event;
}

// Main program and server code:

int
main( int argc, char **argv )
{
int id;

ThreadCtl( _NTO_TCTL_IO, NULL );
SIGEV_INTR_INIT( &event );
id =
InterruptAttach
(
0,
MyIRQ,
NULL,
0,
0
);

printf( “Waiting for Interrupt\n” );
timer = 0;
while( timer < 10000 )
{
InterruptWait( NULL, NULL );

}
printf( “Detaching Interrupt\n” );
InterruptDetach( id );


return 0;
}

In article <b219bo$5ms$1@inn.qnx.com>, randall.nospam.hyde@ustraffic.net says…

Randy,

I understand those were typos… I’ve just read through your post and pointed some… er…
vagueness :slight_smile:

I think the problem is with interrupt rate and your handler. It can’t be handled in such way, you
will lost some interrupts, or, if there is event’s stack, it will overflow… ISR which just does
increment of some variable will work, but your event handler won’t.

You could try another example. It should work on x86 platform (if you’re on PC104 boards, exeptions
are boards from Real Time Devices USA)

ftp://qnx.org.ru/pub/projects/ed1k/clock.tgz

At least, you will able to get an idea.

Cheers,
Eduard.
ed1k at qnxclub dot net

“Eduard” <> ed1k@humber.bay> > wrote in message

ftp://qnx.org.ru/pub/projects/ed1k/clock.tgz

Sorry, it seems you have to point your browser to

ftp://ftp.qnx.org.ru/pub/projects/ed1k/