VxWorks几种常用的延时方法

2008-05-16 15:23:59来源: 单片机及嵌入式系统应用

  嵌入式系统中,一个任务往往需要在特定的延时之后执行一个指定的动作,比如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等。这就需要利用定时器机制来计量特定长度的时间段。VnWorks作为实时嵌入式系统,提供多样的定时接口函数。下面列举一些常用的定时方式,并说明其注意事项。

  1 taskDelav

  taskDelay(n)使调用该函数的任务延时n个tick(内核时钟周期)。该任务在指定的时间内主动放弃CPU,除了taskDelay(0)专用于任务调度(将CPU交给同一优先级的其他任务)外,任务延时也常用于等待某一外部事件,作为一种定时/延时机制。在没有中断触发时,taskDelay能很方便地实现,且不影响系统整体性能。例如写数据至EEPROM,EEPROM需要一个内部擦除时间(最大擦除时间为lOms)。以下所提及的一个tick都假设为16.67 ms(1/60 s)。可以简单地调用taskDelay(2)来保证数据擦写完成。按理说taskDelay(1)就足以保证,为什么需要taskDelay(2)呢?

  这正是taskDelay使用的一个缺陷,使用时需要注意。taskDelay(n)表示任务延时至第n个系统时钟到来的时刻,如图1所示。如果在A时刻调用taskDelay(1)仅延时5 ms,则在B时刻taskDelay(1)就刚好是一个tick周期。可见需要10 ms的延时就必须调用taskDelay(2)才能实现。taskDelay有接近一1个tick的误差存在,taskDelay(n)实际上是延时(n-1)tick~n tick的时间。延时精度为l/n,延时1s就是taskDelay(60)的误差极限为1.6%,而taskDelay(1)的误差极限将是100%。

  使用taskDelay需注意的另外一点是:即使经过n个tick,调用延时的任务也不保证返回执行状态,可能有更高或相同优先级的任务占用了CPU。

  2 WatchDog

  VxWorks提供了一种通用的看门狗定时器机制。利用提供的函数,任何任务都可以创建一个看门狗定时器,经过指定的延时后,实现在系统时钟ISR的上下文中运行指定的程序。需要注意的是,看门狗定时触发的程序是在中断级别上执行,而不是在任务的上下文中。因此,看门狗定时挂接的程序编写有一定的限制,这个限制条件与中断服务程序的约束是一样的。比如,不能使用获取信号量的语句,以及像printf()这样的I/O系统函数。

  通过wdCreate()可以创建一个看门狗定时器。调用wdStart()启动定时器,延时参数同taskDelay一样以tick为单位,同时还须指定定时完成后要调用的程序。如果应用程序同时需要多个看门狗函数,则应使用wdCreate()产生多个独立的看门狗ID。因为对于给定的看门狗ID,通过wdStart()只能关联一个看门狗函数。在指定的tick计数到达之前,要取消一个看门狗计时器,可以通过调用wdCancel()实现。每调用一次wdStart(),看门狗定时器只执行一次,因此对于一些要求周期性执行的应用程序,要获得该效果,则定时器函数本身必须通过递归调用wdStart()来重新启动定时器。

  如果利用看门狗定时器实现延时,则存在与taskDelay一样的精度上的缺陷,以tick为基准.并且看门狗关联的函数所受的限制很大,这也是使用不便的一个方面。不过启动看门狗的任务不会被阻塞,因为wdStart()调用立即返回并继续执行。

  3 sleep/nanosleep

  sleep()和nanosleep()是VxWorks提供的延时函数接口。sleep以s为单位,nanosleep可以提供更精确的延时;传参是时钟的结构体,参数可以精确到ns,但实际上只能做到大于或等于这个时问。因为skep或nanosleep函数延时的时间基准仍是tick,调用此函数的任务处于任务延时状态,这点与taskDelay()一致。不同的地方是,taskDelay()是用于任务调度,taskDelay(O)有其自身的含义,而sleep(O)则是没有意义的。前面提过,taskDelay(n)延时时间为(n-1)tick~ntick,而sleep/nanosleep则保证实际延时时间大于或等于设定的时间参数。这一点可以通过编写一个测试程序试验证明。代码如下:

  

  4 高精度时钟sysTimeStamp

  sysTimeStamp()也称“时间戳”。是通过系统时钟实现的。刚开始也觉得费解,系统时钟的定时周期就是tick,怎么实现高精度时钟呢?通过读BSP底层代码发现,sysTimeStamp其实是通过读取该定时器的当前计数值来获取高精度定时的。通过sysTimestampFreq()函数可以得到系统时间戳的频率,它往往反映的是CPU定时器的基准频率。当然,如此高的分辨率只能是一个理想值,不同的系统不一定都能实现。毕竟该时间戳的实现方式有一个致命的弱点:通过查询方式。系统时钟定时中断是以ticb:为单位的,进一步提高分辨率读取定时器计数值(CPU的一个特殊功能寄存器),只能是查询方式实现。代码示例如下:

  

  这种定时方式比较占用系统资源,且只适用于短时间的定时,但是实现方便。为确保定时准确,应在锁定中断情况下调用sysTimestamp;否则,应考虑使用sysTimes-tampLock函数。

  5 辅助时钟

  辅助时钟是利用目标板上CPU的另一个定时器(除了系统时钟之外)中断实现的。它可以灵活配置实现高分辨率的定时,而且容易实现ms级甚至μs级定时。VxWorks提供了一系列与系统时钟相同的操作接口,用户可以方便地挂接自己的中断处理函数,时钟分辨率的高低取决于硬件定时器的精度和用户中断函数的长短。要将辅助时钟作为精确的延时机制(如ms级延时),可以通过这种方式实现。初始化程序先调用SysAuxClkRateSet()函数设置辅助时钟中断周期为1ms(一般在contig.h文件中AUX_CLK_RATE_MIN和AUX_CLK_RATE_MAX之间,对中断频率作了限定,如果需要可以对此宏定义修改),再通过ysAuxClkConneet()?将用户处理函数连接到辅助时钟中断上,用户处理函数可以为SemGive(semTimer)释放一个同步信号量。编写一个msDelay(intms)作为其他任务调用接口,函数代码如下:

  

  这种方式能实现十分精确的定时,调用延时的任务处于任务阻塞状态。但是使用上仍存在缺陷,不能实现多个任务同时调用,且需要CPU的一个时钟资源,如果没有多余的时钟,那么这一方法就不能实现。

  另外还需要注意一点:Tornado的调试工具Browser一>SpyChart的实现原理是利用辅助定时器产生中断,并记录当前被中断的任务,由抽样数据反映各任务CPU占用率的情况。因此如果调试程序中使用了辅助定时器,那么使用Spy Chart时定时处理函数会被重新挂接,原有定时挂接的程序将得不到进行。反之,如果在Spy Chart运行之后挂接辅助定时处理函数,那么Spy Chart的运行将出现问题。实验发现,运行Spy Chart后重新挂接辅助定时处理函数,Spy Chart即使选中自动刷新,各任务状态也不会更新,如图2所示。

  

  VxWorks提供的定时接口(不一定专门用于定时,也可间接实现)远不只这些。具体使用哪种方式,应根据其精度、资源状态和优先级要求而定。

关键字:taskDelay  函数  VxWorks  基准频率  实时嵌入式系统  sysTim

编辑:孙树宾 引用地址:http://www.eeworld.com.cn/afdz/2008/0516/article_658.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部
taskDelay
函数
VxWorks
基准频率
实时嵌入式系统
sysTim

小广播

独家专题更多

富士通铁电随机存储器FRAM主题展馆
富士通铁电随机存储器FRAM主题展馆
馆内包含了 纵览FRAM、独立FRAM存储器专区、FRAM内置LSI专区三大部分内容。 
走,跟Molex一起去看《中国电子消费品趋势》!
走,跟Molex一起去看《中国电子消费品趋势》!
 
带你走进LED王国——Microchip LED应用专题
带你走进LED王国——Microchip LED应用专题
 

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 视频监控 智能卡 防盗报警 智能管理 处理器 传感器 其他技术 综合资讯 安防论坛

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved