For the most part, 50 ms is an eternity. Just trust the QNX timer unless
you have serious reasons to distrust it.
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();
}
\