VxWorks下几种定时延时方法的小结

合集下载

几种延时方法

几种延时方法

2.2 在C51中嵌套汇编程序段实现延时
在C51中通过预处理指令#pragma asm和#pragma endasm可以嵌套汇编语言语句。用户编写的汇编语言紧跟在#pragma asm之后,在#pragma endasm之前结束。
如:#pragma asm

汇编语言程序段
sbit T_point = P1^0;
void Dly1ms(void) {
unsigned int i,j;
while (1) {
T_point =3;+){
for(j=0;j<124;j++){;}
}
T_point = 0;
for(i=0;i<1;i++){
for(j=0;j<124;j++){;}
}
}
}
void main (void) {
Dly1ms();
}
void Delay10us( ) {
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),所以执行上述函数时共需要10 μs。 可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用[4],以实现较长时间的延时;但需要注意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。

VxWorks系统时钟延时技术

VxWorks系统时钟延时技术

VxWorks几种常用的延时方法介绍2008-06-16 15:12:38 来源:EDN关键字:嵌入式系统;嵌入式系统中,一个任务往往需要在特定的延时之后执行一个指定的动作,比如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等。

这就需要利用定时器机制来计量特定长度的时间段。

VnWorks作为实时嵌入式系统,提供多样的定时接口函数。

下面列举一些常用的定时方式,并说明其注意事项。

1 taskDelavtaskDelay(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。

VxWorks几种常用的延时方法

VxWorks几种常用的延时方法

VxWorks几种常用的延时方法关键字:taskDelay 函数VxWorks 基准频率实时嵌入式系统sysTimes-tampLock 串口通信skep 延时时间tick嵌入式系统中,一个任务往往需要在特定的延时之后执行一个指定的动作,比如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等。

这就需要利用定时器机制来计量特定长度的时间段。

VnWorks作为实时嵌入式系统,提供多样的定时接口函数。

下面列举一些常用的定时方式,并说明其注意事项。

1 taskDelavtaskDelay(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%。

VxWorks中Timer机制

VxWorks中Timer机制

[摘要] Timer是实时操作系统的一个重要组成部分。

本文结合近阶段的学习和实验情况,对VxWorks中的时间函数和定时器作了一些探讨。

主要介绍了Timer的机制,相关的函数,并给出了一些具体的例子。

一. TickTick是指每秒中定时器中断的次数。

POSIX标准中,tick等于50,即每20ms 定时器中断一次。

VxWorks中,tick的缺省设置为60。

因为实时操作系统中,任务的调度和定时器密切相关,tick设置是否合理对整个系统性能的影响是很明显的。

如果tick太小,则系统实时响应能力较差;反之,如果tick太大,则会使得系统的绝大多数资源浪费在不断的任务管理和调度中。

Tick的次数在userconfig.c文件中设置,其语句为sysClkRateSet (60)。

用户可以更改这个文件,然后重新编译BSP库,也可以在应用程序中更改。

和tick相关的函数主要有:sysClkRateGet:得到每秒系统的tick数sysClkRateSet:设置系统的tick数二.看门狗时钟(Watchdog Timer)Watchdog Timer 提供了这样一种机制,它使一个C函数和一个时间延迟联系起来。

当该时间延迟到达以后,系统会调用该C函数。

Watchdog Timer采用了中断服务进程(ISR)的机理,当C函数被激活时,它是作为ISR运行的。

和Watchdog Timer相关的函数如下:wdCreate:创建Watchdog TimerwdDelete:删除Watchdog TimerwdStart:启动一个Watchdog TimerwdCancel:取消一个正在记数的Watchdog Timer Watchdog使用过程如下:首先调用wdCreate创建一个Watchdog Timer, 然后通过wdStart启动该Timer。

当tick累计到设定的数字时,和它相联系的C函数被激活作为ISR运行。

VxWorks几种常用的延时方法

VxWorks几种常用的延时方法
刻 , 图 1所 示 。如 果 在 A 时 刻 调 用 ts Dea ( ) 延 时 如 ak ly 1 仅
只执行一次 , 此对于一 些要求 周期 性执 行 的应用程 序 , 因 要 获 得 该 效 果 , 定 时 器 函 数 本 身 必 须 通 过 递 归 调 用 则
wd tr( 来 重新 启 动 定 时 器 。 Sat)




3 /i k t c


图 1 ts D l a k ea y延 时 示 意 图
些 常 用 的定 时方 式 , 说 明其 注 意 事 项 。 并 1 t s De a a k ly tsD l ( ) 调 用 该 函 数 的 任 务 延 时 个 t k 内 ak ea 使 y i ( c
ts Dea ( ) ? a k ly 2 呢
中断 级 别 上 执 行 , 不 是 在 任 务 的 上 下 文 中 。 因 此 , 门 而 看 狗 定 时 挂 接 的程 序 编 写 有 一定 的 限 制 , 个 限 制 条 件 与 中 这 断 服 务 程 序 的约 束 是 一 样 的 。 比如 , 能 使 用 获 取 信 号 量 不 的语句 , 以及 像 pi f) 样 的 I0 系 统 函数 。 r t(这 n /
过 启 动 看 门狗 的任 务 不 会 被 阻 塞 , 为 wd tr( 调 用 立 因 S at )
() 际 上 是 延 时 ( 1 t k 实 一 )i c
t k的 时 间 。 延 时 精 度 i c
为 1 n 延 时 1S就 是 ts Dea ( 0 的误 差 极 限 为 1 6 , /, ak ly 6 ) . 而 ts Dea ( ) ak ly 1 的误 差 极 限将 是 i 0 。 0

VxWorks下的多重定时器设计

VxWorks下的多重定时器设计

VxWorks下的多重定时器设计VxWorks是一种嵌入式实时操作系统(RTOS),具有内核小、可裁剪、实时性强等特点。

VxWorks内核(Wind)提供了共享内存、信号量、消息队列、套接字通信和定时器等多种机制。

为了实现基于UDP网络的可靠通信,本文利用VxWorks的多种任务间通信机制和看门狗定时器机制,设计了一种多重定时器模型,该模型可以确保数据包的可靠传递。

1.VxWOrks的时钟及定时器机制1.1 VxWorks延时函数VxWorks既提供了延时功能,也提供了时限约束功能。

VxWorks系统有2种延时方式:一种是Wind内核提供的taskDelay()函数;另一种是POSIX函数nanosleep()。

taskDelay()函数以tick作为延时单位,默认情况下1个tick为16.67 ms(1/60 s),可以通过调用sysClkRateSet()函数对tick进行重新设定。

taskDelay()函数使调用该函数的任务在指定时间内主动放弃CPU,用于任务调度或等待某一外部事件。

nanosleep()函数指定一个以s和ns为单位的睡眠或延时时间。

其实,两个延时函数的精度是相同的,都是以tick 为时间基准。

不同之处在于,taskDelay(0)有自身意义,用于相同优先级任务间的任务调度,而nanosleep(0)是没有意义的。

1.2 VxWorks定时器机制VxWorks提供一种看门狗定时器机制(watchdogtimer),可以用来处理任务的时限约束。

看门狗定时器作为系统时钟中断服务程序的一部分来维护,因此,看门狗定时器的回调函数以系统时钟中断级作为中断服务程序执行。

看门狗定时器回调函数受到中断服务程序的限制,不能调用可能引起阻塞的函数,比如试图获取信号量,调用malloc()和free()等创建和释放内存函数或执行I/O操作。

POSIX定时器也可以处理任务时限。

此外,VxWorks中一些函数具有时限控制的功能,semTake()、msgQSend()、msgQReceive()函数中都有设定时限控制的参数。

vxworks通用定时器设计.pdf

vxworks通用定时器设计.pdf
文给 出了定制 定时器 实现 的思想。 关键 词 看 门狗 网络 定 时器
1 概述
v o, WnR e公司开发的具有工业领导 x r 是 i ir W k dv 地位的高性能实时操作系统内核, 具有先进的网络 功能, 易于设计高效的嵌人式系统。目前已成为嵌 人式操作系统的首选, 并将其作为通信产品的软件
为简单, 其流程图如图 4 所
示。
3 结束语
本文介绍了采用 FT算法实现交流采样的原理 F 与具体实现方法。经过实际验证 , 效果 良好。
为了节 约处 理器 的运 算时间,/ A D采样在中断中 进行, 当采样结束后, 置位 采样结束标记 , 监控程序查 询该标 记 , 如果为真 , 调 则 用 FT处理子程序 (I F T 公司 提供了相应的软件包)根 , ( 上接第 4 8页)
要求的定时器。
wDle _ D ; 如果启动看门 d ) , det( wI / e g m 狗不成功, 则删除看门狗 * /
run } e r; t
rt r eu n;
2 通用定时器的基本原理
虽然在 v r 没有提供像 wnos Wo s x k i w 中的定时 d 器一样好用的定时器 , 但可以利用 v o s x r 的看门 W k
{ rt(Eoisr g i aoad rr t i rte ct pn “ r n n o n s i if a t u s e
wt t e \ ; i i r n) h m
够在看门狗的响应函数中重新启动看门狗, 那么就
可以实现以一个固定的周期循环执行的定时器。以 下是定时器的基本框架 : vi st e ( n r l o ei r t v ) d m i ie a t n t
定时肠用户

如何延时方法有哪些

如何延时方法有哪些

如何延时方法有哪些延时是在程序中用于暂停执行一段时间的方法,常用于控制程序的执行节奏和顺序。

在不同的编程语言和开发环境中,延时方法的实现方式可能有所差异。

以下是一些常见的延时方法:1. Sleep方法:Sleep方法是一种最常见的延时方法,它会使程序暂停执行指定的时间间隔。

在C#、Java等编程语言中,可以使用Thread类提供的Sleep方法来实现延时。

例如,在C#中可以使用以下代码实现延时1秒:Thread.Sleep(1000); 延时1秒2. Timer定时器:定时器是一种常用的延时方法,它可以设定一个时间间隔,每隔一段时间触发一次程序代码的执行。

在C#中,可以使用System.Timers.Timer 类来实现定时器,例如:Timer timer = new Timer();timer.Interval = 1000; 设置时间间隔为1秒timer.Elapsed += (sender, e) =>{定时触发的代码逻辑};timer.Start(); 开始定时器3. 延时函数/方法:有些编程语言或开发环境中提供了专门的延时函数或方法,用于实现延时。

例如,在Python中可以使用time模块提供的sleep函数来实现延时,例如:import timetime.sleep(1) # 延时1秒4. 循环延时:循环延时是一种常见的延时方式,它使用循环结构让程序重复执行空操作,从而实现延时效果。

在一些低级语言或单片机编程中,常常使用循环延时,例如在C语言中可以使用以下代码实现延时1秒:#include <stdio.h>#include <time.h>void delay(unsigned int ms){clock_t goal = ms + clock();while (goal > clock());}int main(){delay(1000); 延时1秒return 0;}5. 图形用户界面(GUI)中的延时方法:在一些GUI开发环境中,会提供专门的延时方法或函数,用于实现在用户界面中的延时效果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编程过程中,出于需要,大家或多或少要用到定时/延时。

VxWorks下提供了几种定时/延时机制,根据收集的一些资料和VxWorks相关文档,在学习和上机实验的基础上,对它们的使用以及我所遇到的问题做一个总结,希望对大家能有所帮助。

不正确之处,恳请斧正。

1 taskDelay
taskdelay()提供了一个简单的任务睡眠机制,也常用于需要定时/延时机制的应用中。

它的格式是STATUS taskDelay(int ticks /* number of ticks to delay task */),可以看出使用该函数实现延时的单位为tick(一般系统中一个tick都是ms级的)。

在VxWorks下可以这样使用taskDelay()函数:taskDelay(sysClkRateGet()*1)。

函数sysClkRateGet()返回系统的时钟速率,单位是tick数/每秒(利用函数sysClkRateSet()可以改变系统的时钟速率)。

在POSIX中有一个与taskdelay()相对应的函数――nanosleep()(下文中有介绍)。

这两个函数仅仅是延时单位不同,效果是相同的。

利用taskdelay(),可以将调用的任务移动到具有相同优先级的就绪队列尾部。

特别的,可以通过调用taskdelay(0),将cpu交给系统中其他相同优先级的任务。

延时为0的调用只能用于taskdelay()中,nanosleep()认为这种调用是错误的。

taskdelay()会导致调用的任务在指定的延时期间(以ticks计数)放弃cpu,使任务处于DELAY状态(因此,其不能用于中断服务程序中)。

通常其受到任务调度的影响,但在等待一些与中断无关联的外部条件时,其是有用的。

如果调用的任务受到一个信号,指出其没有被阻塞或被忽略,taskDelay()将返回ERROR,并在信号处理程序运行后设置errno为EINTR。

2 WatchDog
VxWorks提供了一个看门狗定时器(watchdog timer)机制,利用提供的函数,任何任务都可以创建一个看门狗定时器,经过指定的延时后,实现在系统时钟ISR的上下文中运行指定的程序。

在VxWorks中,看门狗定时器作为系统时钟中断服务程序的一部分来维护。

因此,与看门狗定时器相联系的函数运行在系统
时钟中断级。

在使用看门狗定时器实现定时/延时时,经过指定的时间,应用程序中断在系统时钟中断优先级上面,然而,如果内核不能立即执行这个中断服务程序,这个任务就被排队到tExcTask 工作队列中去,处在 tExcTask 工作队列中的任务的优先级为 tExcTask (通常是 0)。

对于使用看门狗定时器的中断服务程序,仍然必须遵守一般的ISR所要遵守的规则。

通过wdCreate( )可以创建一个看门狗定时器。

调用wdStart()启动定时器,延时参数以tick为单位,同时还要指定定时完成后要调用的程序。

如果你的应用程序需要多个看门狗函数,使用wdCreate( )为每个需求产生独立的看门狗ID。

因为对于给定的看门狗ID,只有最近的wdStart()有效。

在指定的tick计数到达之前,要取消一个看门狗计时器,可以调用wdCancel()实现。

每调用一次wdStart(),看门狗定时器只执行一次。

对于一些要求周期性执行的应用程序。

要获得该效果,定时器函数本身必须通过递归调用wdStart()来重新启动定时器。

利用看门狗定时器,调用的任务不会被阻塞:因为wdStart()调用是立即返回的。

使用该方法实现延时,关联函数所受限制太大,好多系统调用不可用,郁闷也…
#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;
}
3 timer(POSIX)
3.1 timer
VxWorks提供IEEE的POSIX 1003.1b标准定时器接口。

使用这种定时器机制,在指定的时间间隔后,任务向自身发信号。

定时器是建立在时钟和信号之上。

程序可以创建创建、设置和删除一个定时器。

当定时器到达期限,将向任务发送默认的信号(SIGALRM)。

使用timer的一般流程:
/* 创建定时器 */
if(timer_create(CLOCK_REALTIME,0,&mytimer)==ERROR)
return(ERROR);
/* 用户程序与定时器相连 */
if(timer_connect(mytimer,(VOIDFUNCPTR)my_handler,0)==ERROR)
return(ERROR);
/* 设置定时器值 */
if(timer_settime(mytimer,0,&value,0)==ERROR)
return(ERROR);
/* 一段延时 */。

/* 删除定时器 */
if (timer_delete(mytimer)==ERROR)
return(ERROR);
在使用定时器时,容易忽略定时结束后任务向自身发信号这一处理步骤。

即在定时结束后,要向创建定时器的任务发送信号,如果此时任务已不存在,定时程序将不能执行,提示的错误是“interrupt: timerWdHandler : kill failed (timer=******,tid=******,errno=0x16)”(有一个《关于timer(定时器)中几个函数的疑问!》帖子,其中提到该问题)。

在上机时,我设置了一个较长时间的定时器,在创建定时器任务中使用相等的延时操作(taskDelay()、nanosleep()随便哪个都行),此时程序正常运行,定时结束后正确地执行关联到定时器的程序;再次运行,在定时结束前,我在shell下删除掉创建定时器的任务,定时结束后又出现上述的错误。

因此,使用POSIX定时器时,一定要注意不能让创建定时器的任务在触发定时程序之前结束,否则。

准备reset吧
3.2 nanosleep()
函数nanosleep()的功能与VxWorks提供的taskDelay()类似,nanosleep()允许指定以秒和纳秒为单位的定时/延时时间,taskDelay()以tick作为定时/延时时间。

两者只是延时单位不同,而不是精度不同,都由系统时钟频率决定。

与taskDelay()一样,使用nanosleep()实现定时/延时的任务也受调度的影响,在实际操作中一定要注意这一点。

使用nanosleep()时,定时参数使用的是结构itimerspe中的it_value,可以指定it_value中的秒和纳秒为定时/延时时间。

函数的使用较为简单,不再赘述。

4 其它
使用带有超时值timeout的msgQReceive()、semTask()也可以实现延时(有使用这种方式来进行延时的人吗?不有吗?有吗?不有吗?有吗?不有吗?。

)。

该方法将阻塞任务,让其等待超时,利用该方法实现延时可以使用函数semTask(…,timeout)、msgQReceive(…,…,…,timeout)。

调用任务被放进阻塞队列中(注意,使用semTask和msgQReceive时,time的值不能是NO_WAIT,如果指定NO_WAIT的话,将立即返回,也就达不到延时的效果了^_^)。

如果你希望任务不被阻塞,还能继续执行,sorry,此法不行,使用看门狗吧。

当阻塞的任务满足继续执行的条件后,将被放入ready队列。

这里要注意的是,任务被放入ready队列并不意味着立刻就被执行。

想想看,如果比它高优先级的任务正在占用资源,或也在等资源,那么…延时将是不确定的。

相关文档
最新文档