ISR about isr 8

Now I need to write a relative precise timer (50ms )program with ISR.
I wish use the IRQ 8,because someone say that its accuracy is very high.
So I test irq 8 in the simply “test.c” ,When I run the program ,no interrupt
happened.
I think maybe something wrong with my code.But I don’t know where?
And how to use that to create 50 ms timer interrupt with IRQ 8?

the test.c code :

#include <stdio.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>

#define IRQ_8 8

struct sigevent event;
volatile unsigned counter;

const struct sigevent *handler( void *area, int id ) {
// Wake up the thread every 100’th interrupt
if ( ++counter == 100 ) {
counter = 0;
return( &event );
}
else
return( NULL );
}

int main() {
int i;
int id;

// Request I/O privity
ThreadCtl( _NTO_TCTL_IO, 0 );

// Initialize event structure
event.sigev_notify = SIGEV_INTR;

// Attach ISR vector
id=InterruptAttach( IRQ_8, &handler,
NULL, 0, 0 );

for( i = 0; i < 10; ++i ) {
// Wait for ISR to wake us up
InterruptWait( 0, NULL );
printf( “100 events\n” );
}

// Disconnect the ISR handler
InterruptDetach(id);
return 0;
}

zhz_zhang <zhz_zhang@263.net> wrote in article <a1m9q5$hib$1@inn.qnx.com>…

Now I need to write a relative precise timer (50ms )program with ISR.
I wish use the IRQ 8,because someone say that its accuracy is very high.

Do you mean INT 8 (IRQ 0) on x86 platform? It’s hardware interrupt on PC/AT and it should happens
every 55ms (about 18.2 times per second). IMO it’s not very accuracy and I’m not sure it is
possible to use it in QNX. There was some tricks in DOS to use this hardware for creating more
accuracy timer, but… I guess QNX has other tools, more flexible and platform independed…

Anyhow, I don’t know you should to pass interrupt number (position of vector in table) or interrupt
line number. Maybe problem is here…

Best regards,
Eduard.

So I test irq 8 in the simply “test.c” ,When I run the program ,no interrupt
happened.
I think maybe something wrong with my code.But I don’t know where?
And how to use that to create 50 ms timer interrupt with IRQ 8?

the test.c code :

#include <stdio.h
#include <sys/neutrino.h
#include <sys/syspage.h

#define IRQ_8 8

struct sigevent event;
volatile unsigned counter;

const struct sigevent *handler( void *area, int id ) {
// Wake up the thread every 100’th interrupt
if ( ++counter == 100 ) {
counter = 0;
return( &event );
}
else
return( NULL );
}

int main() {
int i;
int id;

// Request I/O privity
ThreadCtl( _NTO_TCTL_IO, 0 );

// Initialize event structure
event.sigev_notify = SIGEV_INTR;

// Attach ISR vector
id=InterruptAttach( IRQ_8, &handler,
NULL, 0, 0 );

for( i = 0; i < 10; ++i ) {
// Wait for ISR to wake us up
InterruptWait( 0, NULL );
printf( “100 events\n” );
}

// Disconnect the ISR handler
InterruptDetach(id);
return 0;
}
\

In accordance with documentation
http://www.qdn.com/support/docs/neutrino/lib_ref/i/interruptattach.html
you have to use intr=0 as first argument of InterruptAttach()

Also you could read there:
interrupt 0 - Clock that runs at resolution set by ClockPeriod()

So, QNX seems to use this hardware on x86 platform for itself in order to give you better way to
solve the problem. Timeslice is 1 ms in QNXRTP (>40 Mhz), so it’s much better than 55 ms :wink:)

Good luck!
Eduard.

zhz_zhang wrote:

Now I need to write a relative precise timer (50ms )program with ISR.
I wish use the IRQ 8,because someone say that its accuracy is very high.
So I test irq 8 in the simply “test.c” ,When I run the program ,no interrupt
happened.
I think maybe something wrong with my code.But I don’t know where?
And how to use that to create 50 ms timer interrupt with IRQ 8?

The attached code works for me. Of course, there is no setting on the
12887 that corresponds directly to 50ms, but you could use 1KHz and only
send a pulse every 50 interrupts.

I am curious though, QNX should be able to easily schedule an accurate
50ms with the system timers without resorting to HW dependent timers;
why do feel the system timers are not accurate enough ?

Rennie

ed1k says:

you have to use intr=0 as first argument of InterruptAttach()

Also you could read there:
interrupt 0 - Clock that runs at resolution set by ClockPeriod()

So, QNX seems to use this hardware on x86 platform for itself in order to
give you better way to
solve the problem. Timeslice is 1 ms in QNXRTP (>40 Mhz), so it’s much
better than 55 ms > :wink:> )

Good luck!
Eduard.

sorry for my unwisdom.

I don’t understand the IRQ 0,is system timer,what difference between IRQ 0
system time and the cpu clock(frequence).
whether if I use ClockPeriod to set the clock,all the program running speed
,will be slow down.

Appreciate your help,now i have other two question.
1.As you say,QNX have system timer ,I am beginner ,is QNX system timer very
accurate?
if I want a accuracy 50ms timer,can QNX system timer finish it very
well?
Do I need a additional extern hardware timer board Specially?

2.Sorry for my obtrusion,do you have some document about IRQ 8 in detail,
as you write in you
code ,I want know more about 12887 Real Time Clock .

“Rennie Allen” <rallen@csical.com> wrote in message
news:3C3F2B0F.1010308@csical.com

zhz_zhang wrote:

Now I need to write a relative precise timer (50ms )program with ISR.
I wish use the IRQ 8,because someone say that its accuracy is very high.
So I test irq 8 in the simply “test.c” ,When I run the program ,no
interrupt
happened.
I think maybe something wrong with my code.But I don’t know where?
And how to use that to create 50 ms timer interrupt with IRQ 8?




The attached code works for me. Of course, there is no setting on the
12887 that corresponds directly to 50ms, but you could use 1KHz and only
send a pulse every 50 interrupts.

I am curious though, QNX should be able to easily schedule an accurate
50ms with the system timers without resorting to HW dependent timers;
why do feel the system timers are not accurate enough ?

Rennie





#include <sys/neutrino.h
#include <sys/siginfo.h
#include <hw/inout.h

/* registers on 12887 Real Time Clock */

#define RTC_CMD_ADDR 0x70 // RTC internal register offset goes here
#define RTC_DAT_ADDR 0x71 // RTC internal register R/W access here

#define RTC_REG_A 0x0A // RTC register offset for accessing Reg. A
#define RTC_REG_B 0x0B // RTC register offset for accessing Reg. B
#define RTC_REG_C 0x0C // RTC register offset for accessing Reg. C
#define RTC_REG_D 0x0D // RTC register offset for accessing Reg. D

#define RTC_IRQ 8

typedef enum { KHz8=3,
KHz4,
KHz2,
KHz1,
Hz512,
Hz256,
Hz128,
Hz64,
Hz32,
Hz16,
Hz8,
Hz4,
Hz2 } DS12887_rate_selector_t;

void enable_DS12887_periodic_intr(DS12887_rate_selector_t hz)
{
InterruptDisable();
out8( RTC_CMD_ADDR, RTC_REG_B ); // select RTC register B
out8( RTC_DAT_ADDR, 0x42 ); // set Periodic Interrupt Enable bit

out8( RTC_CMD_ADDR, RTC_REG_A ); // select RTC register A
out8( RTC_DAT_ADDR, 0x20 | hz ); // set rate, oscillator enabled
InterruptEnable();
}

void disable_DS12887_periodic_intr(void)
{
InterruptDisable();
out8( RTC_CMD_ADDR, RTC_REG_B );
out8( RTC_DAT_ADDR, 0x02 );

out8( RTC_CMD_ADDR, RTC_REG_A );
out8( RTC_DAT_ADDR, 0x28 );
InterruptEnable();
}

int main(void)
{
struct sigevent event;
int ctr=0;
int intr_id;

ThreadCtl(_NTO_TCTL_IO, 0);

out8(RTC_CMD_ADDR, RTC_REG_C );
in8( RTC_DAT_ADDR );

enable_DS12887_periodic_intr(Hz512);

SIGEV_INTR_INIT(&event);

intr_id=InterruptAttachEvent(RTC_IRQ, &event, _NTO_INTR_FLAGS_END);

while(1) {
InterruptWait(0,NULL);

out8(RTC_CMD_ADDR, RTC_REG_C );
in8( RTC_DAT_ADDR );

InterruptUnmask(RTC_IRQ, intr_id);

if((ctr++)%512 == 0) {
printf(“counter = %d\n”, ctr-1);
}
}
disable_DS12887_periodic_intr();
}

The QNX timer is driver from the hardware timer so it is no more or less
accurate than the hardware. However there are two other issues that you
might want to consider.

  1. from the time that the interrupt SHOULD occur to the time that your
    process will be notified there is a latency. This latency should be very
    short but will depend on what else is happening in oyur system, i.e. does
    anything have hardware interrupts turned off, are there any other processes
    running at a higher priority. Even so, this latency should be way under a
    milli-second.

  2. if the latency above ever exceeds your period then you will loose
    accuracy.

For the most part, 50 ms is an eternity. Just trust the QNX timer unless
you have serious reasons to distrust it.


Bill Caroselli – 1(530) 510-7292
Q-TPS Consulting
QTPS@EarthLink.net


“zhz_zhang” <zhz_zhang@263.net> wrote in message
news:a1p3re$jcn$1@inn.qnx.com

Appreciate your help,now i have other two question.
1.As you say,QNX have system timer ,I am beginner ,is QNX system timer
very
accurate?
if I want a accuracy 50ms timer,can QNX system timer finish it very
well?
Do I need a additional extern hardware timer board Specially?

2.Sorry for my obtrusion,do you have some document about IRQ 8 in
detail,
as you write in you
code ,I want know more about 12887 Real Time Clock .

“Rennie Allen” <> rallen@csical.com> > wrote in message
news:> 3C3F2B0F.1010308@csical.com> …
zhz_zhang wrote:

Now I need to write a relative precise timer (50ms )program with ISR.
I wish use the IRQ 8,because someone say that its accuracy is very
high.
So I test irq 8 in the simply “test.c” ,When I run the program ,no
interrupt
happened.
I think maybe something wrong with my code.But I don’t know where?
And how to use that to create 50 ms timer interrupt with IRQ 8?




The attached code works for me. Of course, there is no setting on the
12887 that corresponds directly to 50ms, but you could use 1KHz and only
send a pulse every 50 interrupts.

I am curious though, QNX should be able to easily schedule an accurate
50ms with the system timers without resorting to HW dependent timers;
why do feel the system timers are not accurate enough ?

Rennie


\



#include <sys/neutrino.h
#include <sys/siginfo.h
#include <hw/inout.h

/* registers on 12887 Real Time Clock */

#define RTC_CMD_ADDR 0x70 // RTC internal register offset goes here
#define RTC_DAT_ADDR 0x71 // RTC internal register R/W access here

#define RTC_REG_A 0x0A // RTC register offset for accessing Reg. A
#define RTC_REG_B 0x0B // RTC register offset for accessing Reg. B
#define RTC_REG_C 0x0C // RTC register offset for accessing Reg. C
#define RTC_REG_D 0x0D // RTC register offset for accessing Reg. D

#define RTC_IRQ 8

typedef enum { KHz8=3,
KHz4,
KHz2,
KHz1,
Hz512,
Hz256,
Hz128,
Hz64,
Hz32,
Hz16,
Hz8,
Hz4,
Hz2 } DS12887_rate_selector_t;

void enable_DS12887_periodic_intr(DS12887_rate_selector_t hz)
{
InterruptDisable();
out8( RTC_CMD_ADDR, RTC_REG_B ); // select RTC register B
out8( RTC_DAT_ADDR, 0x42 ); // set Periodic Interrupt Enable bit

out8( RTC_CMD_ADDR, RTC_REG_A ); // select RTC register A
out8( RTC_DAT_ADDR, 0x20 | hz ); // set rate, oscillator enabled
InterruptEnable();
}

void disable_DS12887_periodic_intr(void)
{
InterruptDisable();
out8( RTC_CMD_ADDR, RTC_REG_B );
out8( RTC_DAT_ADDR, 0x02 );

out8( RTC_CMD_ADDR, RTC_REG_A );
out8( RTC_DAT_ADDR, 0x28 );
InterruptEnable();
}

int main(void)
{
struct sigevent event;
int ctr=0;
int intr_id;

ThreadCtl(_NTO_TCTL_IO, 0);

out8(RTC_CMD_ADDR, RTC_REG_C );
in8( RTC_DAT_ADDR );

enable_DS12887_periodic_intr(Hz512);

SIGEV_INTR_INIT(&event);

intr_id=InterruptAttachEvent(RTC_IRQ, &event, _NTO_INTR_FLAGS_END);

while(1) {
InterruptWait(0,NULL);

out8(RTC_CMD_ADDR, RTC_REG_C );
in8( RTC_DAT_ADDR );

InterruptUnmask(RTC_IRQ, intr_id);

if((ctr++)%512 == 0) {
printf(“counter = %d\n”, ctr-1);
}
}
disable_DS12887_periodic_intr();
}





\

“zhz_zhang” <zhz_zhang@263.net> wrote in message
news:a1p3p8$jc4$1@inn.qnx.com

ed1k says:

you have to use intr=0 as first argument of InterruptAttach()

Also you could read there:
interrupt 0 - Clock that runs at resolution set by ClockPeriod()

So, QNX seems to use this hardware on x86 platform for itself in order
to
give you better way to
solve the problem. Timeslice is 1 ms in QNXRTP (>40 Mhz), so it’s much
better than 55 ms > :wink:> )

Good luck!
Eduard.

sorry for my unwisdom.
I don’t understand the IRQ 0,is system timer,what difference between IRQ 0
system time and the cpu clock(frequence).

  • IRQ 0 is an interrupt that is fired when a hardware timer expires.
  • The system time is maintain via an OS installed interrupt handler on IRQ
  • Time is also maintain by a real time clock. Typical the time is read from
    the RTC into the system time at startup (check rtc utility)
  • The CPU clock is totaly irrelevant to timer precision

whether if I use ClockPeriod to set the clock,all the program running
speed
,will be slow down.

So very slightly. What happens is you will have more IRQ0 being fired.
By default it’s 1ms pn CPU >40Mzh I beleive.

I suggest you read: http://qdn.qnx.com/articles/oct2300/quantization.html
and http://qdn.qnx.com/articles/oct3100/concept_of_time.html

Now you mention 50ms, but you didn’t say at which precision you need
this. For example if you need 50ms ± 1 ns, forget it hardware isn’t
hable. If you need 50ms ± 1ms that’s not a big deal. If you need 50ms ±
1us, that a little more tricky but can be done.

  • Mario



zhz_zhang wrote:

Appreciate your help,now i have other two question.
1.As you say,QNX have system timer ,I am beginner ,is QNX system timer very
accurate?
if I want a accuracy 50ms timer,can QNX system timer finish it very
well?

As Mario mentioned in elsewhere in this thread, 50ms ± what ? Since
the units you specified are milliseconds, then the implication is that
the accuracy you want is measured in those units, and if this is true,
then QNX system timers can easily give you 50ms ±1 unit (ms). As Mario
said if you’re careful, 50000 usec ±1 usec is possible (depending on
your hardware of course).


Do I need a additional extern hardware timer board Specially?

No, the DS12887 is built-in to your motherboard (if you have a desktop PC).


2.Sorry for my obtrusion,do you have some document about IRQ 8 in detail,
as you write in you
code ,I want know more about 12887 Real Time Clock .

There are gobs of references on the web. Google for “DS12887 programming”.

Thank everybody 's help.Thank you!
Hongzhi Zhang