VxWorks提供丰富的定时管理和时钟管理,主要应用在以下几个方面:
? 维护系统日历时钟
? 在任务等待信号量、消息、事件(VxWorks5.5版本以上)或内存段时的超时处理。(系统提供的函数调用都有关于timeout的参数设置。)
? 以一定的时间间隔或在特定的时间唤醒或发送告警到一个任务。
? 处理任务调度中的时间片轮转。
VxWorks系统这些功能都依赖于周期性的定时中断,离开实时时钟或定时器硬件就无法工作。介绍几个常用的系统调用:
l sysClkConnect( )――连接系统时钟中断服务程序(sysLib.h)
函数原型:――connect a routine to the system clock interrupt STATUS sysClkConnect ( FUNCPTR routine, /* routine called at each system clock interrupt */ int arg /* argument with which to call routine */ )
l sysClkRateSet( )――设置每秒钟系统时钟中断次数(既每秒钟的tick数)(sysLib.h) 函数原型:――set the system clock rate STATUS sysClkRateSet ( int ticksPerSecond /* number of clock interrupts per second */ )
l sysClkEnable ( )――使能系统时钟中断(sysLib.h)
函数原型:――turn on system clock interrupts
void sysClkEnable (void)
系统定时器的设置是在usrConfig.c中通过usrRoot( )函数完成的,主要就是调用以上三个函数,代码如下:
/* set up system timer */
sysClkConnect ((FUNCPTR) usrClock, 0); /* connect clock ISR */
sysClkRateSet (SYS_CLK_RATE); /* set system clock rate */
sysClkEnable (); /* start it */
其中usrClock( )也是在usrConfig.c中定义的,函数只是通知系统内核时钟tick。
void usrClock ()
{
tickAnnounce (); /* announce system tick to kernel */
}
(有关tickLib.h中的函数以后再介绍)
而系统时钟频率SYS_CLK_RATE的值在congfigAll.h中定义为60,代码如下:
#define SYS_CLK_RATE 60 /* default system clock rate */
你可以通过改这个值来自己设置系统时钟中断频率,一般在60到100,但不能大于600。SYS_CLK_RATE只设置的过大会增加任务切换开销。
l sysClkRateGet( )――得到每秒钟系统时钟中断次数(既每秒钟的tick数)(sysLib.h)
函数原型:――get the system clock rate
int sysClkRateGet (void)
[此贴子已经被作者于2004-5-31 17:13:36编辑过] --------------------------------------------------------------------------------
学习总结:VxWorks的定时与时钟管理2
http://bbs.edw.com.cn/dispbbs.asp?boardID="3"&ID="29415"&page="1"
自己的一个小程序:(如何使用sysCkRateSet和sysClkRateGet)
/**********************************/ #i nclude "vxWorks.h" #i nclude "sysLib.h"
#i nclude "stdio.h" void test() { int TimeRate,NumB; TimeRate = 100; if(sysClkRateSet(TimeRate) ==ERROR) { printf("Error in setting rate!\n"); } NumB = sysClkRateGet(); printf("NumB = %d\n",NumB); } 运行结果: -> test NumB = 100 value = 11 = 0xb = __major_os_version__ + 0x7 l tickAnnounce( )――通知系统内核时钟tick 函数原型:――announce a clock tick to the kernel void tickAnnounce (void) 它被usrConfig.c中的usrClock( )调用,而usrClock( )又是系统时钟中断服务程序,想让应用程序运行在系统时钟中断级,则可将其加在ursClock程序里。 l tickSet( )――设置内核时钟计数器值(内核tick的数) 函数原型:――set the value of the kernel's tick counter void tickSet ( ULONG ticks /* new time in ticks */ ) l tickGet( )――得到内核时钟计数器值 函数原型:――get the value of the kernel's tick counter ULONG tickGet (void) 下面两个例子: /**********例一:用tickGet获得现在内核tick定时器的tick数******************/ #i nclude "vxWorks.h" #i nclude "tickLib.h" #i nclude "stdio.h" #i nclude "taskLib.h" #i nclude "logLib.h" void test() { ULONG TickCounts; for(int i="0";i<5;i++) { TickCounts = tickGet(); logMsg("TickCounts = %d\n",TickCounts,0,0,0,0,0); taskDelay(100); } } 运行结果:(在目标仿真器上输出) 0x12892b8 (t12): TickCounts = 299830 0x12892b8 (t12): TickCounts = 299930 0x12892b8 (t12): TickCounts = 300030 0x12892b8 (t12): TickCounts = 300130 0x12892b8 (t12): TickCounts = 300230 如果将上面的logMsg换为printf,则输出在shell中(注意两种输出的区别)。 /***********例二:tickSet和tickGet的使用例程************************/ #i nclude "vxWorks.h" #i nclude "tickLib.h" #i nclude "stdio.h" #i nclude "taskLib.h" void test() { ULONG TickCountSet = 0; tickSet(TickCountSet); for(int i="0";i<5;i++) { ULONG TickCounts = tickGet(); printf("TickCounts = %d\n",TickCounts); taskDelay(100); } } 运行结果: -> test TickCounts = 0 TickCounts = 100 TickCounts = 200 TickCounts = 300 TickCounts = 400 value = 0 = 0x0
|
shenyandetongxing_551209819 2006-12-25 12:31
shenyandetongxing_551209819 2006-11-5 00:12
可以用Watchdog定时器吧。
#define TICK_MS (1000/SYS_CLK_RATE)/*每tick的毫秒数*/
int timer_array[30];
void timer_run()/*定时器调用函数*/
{wdStart(timer_ID,timerLength/TICK_MS,(FUNCPTR)(timer_run),0);}
UINT16 SimOs_SetTimer(UINT16 timerID, ULONG timerLength) /*系统定时*/
{
WDOG_ID timer_ID;
extern int timer_array[];
timer_ID="wdCreate"();/*创建定时器*/
timer_array[timerID]=(int)timer_ID;
if(timerLength==0)
timerLength="1";
wdStart(timer_ID,timerLength/TICK_MS,(FUNCPTR)(timer_run),0);/*打开定时器*/
}
/*清除系统定时*/
UINT16 SimOs_KillTimer(UINT16 timerID)
{
extern int timer_array[30];
WDOG_ID timer_ID;
timer_ID=(WDOG_ID)timer_array[timerID];
if(wdDelete(timer_ID)==OK)
return XW_TRUE;
}
参考一下吧,这是以前的一个测试的程序
用户75753 2006-11-4 21:18
用户824863 2006-8-25 17:29
用户824863 2006-8-25 17:08