新闻  |   论坛  |   博客  |   在线研讨会
FreeRTOS两种延时函数的区别是什么?
13261589816 | 2022-07-19 15:15:23    阅读:1398   发布文章

FreeRTOS提供了两个系统延时函数:相对延时函数vTaskDelay()和绝对延时函数vTaskDelayUntil()。

· 相对延时:指每次延时都是从任务执行函数vTaskDelay()开始,延时指定的时间结束。

· 绝对延时:指每隔指定的时间,执行一次调用vTaskDelayUntil()函数的任务。


相对延时函数

函数原型:void vTaskDelay( portTickType  xTicksToDelay )

函数参数xTicksToDelay:延时的时间长度,单位是系统时钟节拍周期

函数用法分析:调用vTaskDelay()函数后,任务会进入阻塞状态,持续时间由参数xTicksToDelay指定,单位是系统节拍时钟周期。延时时间是从调用vTaskDelay()后开始计算的相对时间。比如vTaskDelay(100),那么从调用vTaskDelay()后,任务进入阻塞状态,经过100个系统时钟节拍周期后任务解除阻塞。

使用示例如下,示例中系统时钟节拍设置为1ms,包含红色和绿色LED两个用户任务,绿色LED任务的优先级最高。在绿色LED闪烁的任务中,调用vTaskDelay函数延时100ms,执行绿色LED任务需要50ms,任务再次执行的时间间隔为延时时间100ms加上任务执行花费的50ms共计150ms。低优先级的红色LED任务执行10ms。

图片

图1

图片

图2

因为绿色LED任务为系统中最高优先级任务,会抢占低优先级红色LED任务执行,所以执行过程中红色LED任务并不会对vTaskDelay函数造成影响。绿色LED任务再次执行的时间间隔为延时时间加上任务本身所用的时间,即延时时间100ms加上任务执行时间50ms共150ms。在Tracealyzer中的跟踪视图中显示的时间间隔图3所示。

图片

图3

如果调用vTaskDelay()函数的任务在执行过程中被更高优先级的任务或者中断所打断,那么调用vTaskDelay()函数的任务将会受到影响,此时将不能保持一个固定的时间间隔运行。

继续上文的例子,如果我们将绿色LED任务和红色LED任务的优先级进行调换,那么绿色LED任务在执行过程中将被红色LED任务打断,那么我们可以再分析一下此时该任务的执行情况。Tracealyzer的跟踪视图如图4所示,可以看到绿色LED任务在执行过程中被红色LED任务抢占,红色LED任务执行了10ms,因此绿色LED任务的执行间隔增加10ms变为了160ms。

红色LED是否会抢占绿色LED任务,以及何时发生任务抢占都是难以预知的,因此绿色LED任务的执行间隔或频率也变得难以预测,这是在使用vTaskDelay()函数时需要注意的事项。

图片

图4

如果我们想要任务以固定的时间间隔重复运行,那么可以使用绝对延时函数。


绝对延时函数

函数原型:void vTaskDelayUntil( portTickType  *pxPreviousWakeTime, portTickType  xTimeIncrement );

函数参数:

pxPreviousWakeTime:指针,指向一个变量,该变量保存任务最后一次解除阻塞的时间。第一次使用前,该变量必须初始化为当前时间。之后这个变量会在vTaskDelayUntil()函数内自动更新。

xTimeIncrement:绝对延时时间,即任务重复执行的时间间隔。

将上述例子中的vTaskDelay()函数替换为vTaskDelayUntil()函数,红色LED任务的优先级同样高于绿色LED任务。

图片

图5

再次运行得到的跟踪视图如图6所示,可以看到此时系统中仍然发生了任务抢占,但是绿色LED任务的执行时间间隔为我们通过vTaskDelayUntil()函数指定的100ms。

图片

调用vTaskDelayUntil()函数时,绝对延时的时间包含该任务本身的执行时间,以及任务被打断的时间。例如绿色LED任务执行所用的50ms,以及红色任务抢占占用的10ms,都属于绝对延时的时间范围内。任务执行过程中被短暂打断也不会影响绝对延时,从而保证任务能够以设定的时间周期重复运行。相对延时的时间则不会包含任务本身的执行时间和任务被打断的时间,这一点是两种延时函数之间的重要区别。

注意事项:

如果任务延时过程中被打断的时间太长,回来之后延时都超过了,那么则会立马执行程序,不会再执行延时操作(任务不会再阻塞延时)。

上述示例中我们调用vTaskDelayUntil()函数的任务优先级为最高优先级任务,但实际应用中可能并非如此,因此该任务依然可能被中断或者更高优先级的任务打断,此时vTaskDelayUntil()函数延时时间到了之后该任务将恢复就绪状态,但无法保证该任务能够马上执行。

两种延时函数都面临可能存在的中断或者高优先级任务打断的问题,无法保证任务一定能够以指定的时间间隔重复运行,因此实践中还需要借助类似Tracealyzer这样的RTOS可视化分析工具进一步分析来保证RTOS复杂应用的可靠性。

想学习并了解Tracezlyzer更多信息和知识,可以参考《嵌入式实时操作系统-基于STM32Cube、FreeRTOS和Tracealyzer的应用开发》图书!

图片


欢迎关注微信公众号【麦克泰技术】


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
北京麦克泰软件技术有限公司(中文简称麦克泰,英文简称 BMR)成立于1995年, 是国内专业的嵌入式系统软件企业,与世界领先的嵌入式软件供应商合作有二十多年的时间,为嵌入式研发提供丰富的工具,软件,解决方案和培训服务。
推荐文章
最近访客