延时函数

vTaskDelay()

相对延时函数,在文件task.c中定义的,要使用的话宏INCLUDE_vTaskDelay必须设置为1;

void vTaskDelay( const TickType_t xTicksToDelay )
{
BaseType_t xAlreadyYielded = pdFALSE; /* A delay time of zero just forces a reschedule. */
if( xTicksToDelay > ( TickType_t ) 0U )
{
configASSERT( uxSchedulerSuspended == 0 );
vTaskSuspendAll();
{
traceTASK_DELAY();
prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );
}
xAlreadyYielded = xTaskResumeAll();
}
else
{
mtCOVERAGE_TEST_MARKER();
} if( xAlreadyYielded == pdFALSE )
{
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
  • 延时参数xTicksToDelay为要延时的时间节拍数,肯定要大于0,否则相当于直接调用函数portYIELD()进行任务切换;
  • 调用vTaskSuspendAll()挂起任务调度器;
  • 调用函数prvAddCurrentTaskToDelayedList()将要延时的任务添加到延时列表中;
  • 调用xTaskResumeAll()恢复任务调度器,并在之后检测xTaskResumeAll()返回参数,如果没进行任务调度的话,那么调用portYIELD_WITHIN_API()进行任务调度;

函数prvAddCurrentTaskToDelayedList()分析

static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely )
{
TickType_t xTimeToWake;
const TickType_t xConstTickCount = xTickCount; #if( INCLUDE_xTaskAbortDelay == 1 )
{
pxCurrentTCB->ucDelayAborted = pdFALSE;
}
#endif if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
}
else
{
mtCOVERAGE_TEST_MARKER();
} #if ( INCLUDE_vTaskSuspend == 1 )
{
if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) )
{
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else
{
xTimeToWake = xConstTickCount + xTicksToWait;
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake );
if( xTimeToWake < xConstTickCount )
{
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else
{
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
if( xTimeToWake < xNextTaskUnblockTime )
{
xNextTaskUnblockTime = xTimeToWake;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
}
#else /* INCLUDE_vTaskSuspend */
{
xTimeToWake = xConstTickCount + xTicksToWait;
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount )
{
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else
{
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
if( xTimeToWake < xNextTaskUnblockTime )
{
xNextTaskUnblockTime = xTimeToWake;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
} ( void ) xCanBlockIndefinitely;
}
#endif /* INCLUDE_vTaskSuspend */
}
  • 读取进入该函数的时间点并保存在xConstTickCount中,后面在计算唤醒时间点的时候要用到,xTickCount是时钟节拍计数器,每个滴答定时器中断xTickCount都会加一
  • 将当前任务从就绪表中移除;
  • 取消当前任务在uxTopReadyPriority中的就绪标记,即将相应的bit清0;
  • 如果延时时间为最大值portMAX_DELAY并且xCanBlockIndefinitely不为pdFALSE(即表示允许阻塞任务),那么直接将当前任务添加到挂起列表中,任务就不用添加到延时列表中了;
  • 计算唤醒的时间点,之后将唤醒时间点值写入到任务列表中状态列表项的相应字段中;
  • 如果计算得到的唤醒时间点小于xConstTickCount说明发生了溢出,FreeRTOS针对此现象专门做了处理,定义了两个延时列表xDelayedTaskList1和xDelayedTaskList2,也定义了两个指针pxDelayedTaskList和pxOverflowDelayedTaskList来访问这两个列表,在初始化列表函数中分别进行了初始化;
  • xNextTaskUnblockTime是个全局变量,保存着距离下一个要取消阻塞的任务最小时间点值,当计算的唤醒时间点xTimeToWake小于xNextTaskUnblockTime,就更新替换;

vTaskDelayUntil()

绝对延时函数,该函数会阻塞任务,阻塞时间是一个绝对时间,如果是一些需要按照一定的频率运行的任务可以使用该函数;

函数定义如下:

void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
  • pxPreviousWakeTime,上一次任务延时结束被唤醒的时间点,任务中第一次调用该函数时需要将pxPreviousWakeTime初始化进任务的while()循环体的时间点值,之后的运行中该函数会自动更新pxPreviousWakeTime的值;
  • xTimeIncrement,任务需要延时的时间节拍数;

使用模板如下:

void test_task(void *pvParameters)
{
TickType_t PreviousWakeTime; //延时50ms,将延时时间转换成节拍数
const TickType_t TimeIncrement = pdMS_TO_TICKS(50);
PreviousWakeTime = xTaskGetTickCount(); //获取当前的系统节拍值
for( ; ; )
{
/* 任务主体 */ /* 调用延时函数 */
vTaskDelayUntil(&PreviousWakeTime, TimeIncrement);
}
}

注意:使用函数vTaskDelayUntil()延时的任务也不一定就能周期性的运行,只能保证按照一定的周期取消阻塞,进入就绪态,如果有更高优先级或者中断的话,还是要等待其他更高优先级任务或者中断服务函数运行完成后才能运行;

FreeRTOS时间管理的更多相关文章

  1. uC/OS-III 时钟节拍,时间管理,时间片调度

    uC/OS-III 时钟节拍,时间管理,时间片调度   时钟节拍 时钟节拍可谓是 uC/OS 操作系统的心脏,它若不跳动,整个系统都将会瘫痪. 时钟节拍就是操作系统的时基,操作系统要实现时间上的管理, ...

  2. FreeRTOS-04-内核控制函数+时间管理函数

    说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...

  3. PMP备考_第六章_项目时间管理

    项目时间管理 前言 项目时间管理是项目管理中最难的一个环节,与个人时间管理类似,团体的效率如果管理不当,是低于个人效率的,为了管理好时间,从预估,执行到反馈均需要严格的分析和处理.如果制定的计划是无法 ...

  4. Google内部邮件:如何进行高效的时间管理能量波动图

    Google内部邮件:如何进行高效的时间管理能量波动图 发布时间: 2015-12-16 22:16:50| 阅读数:462 views 最近,我给团队内部写了一封简单的邮件.主要内容是征询他们,如何 ...

  5. linux 时间管理——概念、注意点(一)【转】

    转自:http://www.cnblogs.com/openix/p/3324243.html 参考:1.http://bbs.eyeler.com/thread-69-1-1.html        ...

  6. μC/OS-Ⅲ系统的时间管理函数和定时器

    一.时间管理函数 μC/OS-Ⅲ系统提供一些列时间管理服务函数: 1.OSTimeDly():任务延时n个时钟节拍. 2.OSTimeDlyHMSM():任务延时指定的时间,采用“时:分:秒:毫秒”方 ...

  7. 时间管理的若干Tips

    时间管理的若干Tips 记下来 再好的记性也不如一支笔与一个本子. 买一支好点的笔于一个好点的本子,让自己有书写的欲望,将todo事项记下来. 小目标 太大太远的目标会使人气馁.通过将大目标分解再分解 ...

  8. 4D时间管理

    时间管理的4D原则   时间矩阵:每个人,每天要做的事情大致分为四类:一类:必须做的,不做会产生不良后果的二类:需要做的,为将来或者今后阶段做准备工作的三类:可以不做,但又不得不做的,例如通过简约形式 ...

  9. 【uTenux实验】时间管理(系统时间/周期性处理/警报处理)

    1.系统时间管理 系统时间管理函数用来对系统时间进行操作,是OS的一个基础性的东西.个人认为,设置系统时间和获取系统时间对OS来说基本是可有可无的. uTenux提供了三个系统时间相关API.分别用于 ...

随机推荐

  1. 搭建iOS开发环境

    搭建ios开发环境 1.  直接购买Apple公司的电脑,如MacBook笔记本电脑,默认自带了Mac OS X操作系统. 2.下载安装Xcode和SDK     登录https://develope ...

  2. Quartz.Net入门 - Net作业调度

    背景 很多时候,项目需要在不同时刻,执行一个或很多个不同的作业. Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架. 介绍 Quartz一个开源 ...

  3. js中实现base64加密、解密

    //base64加密 解密 /* //1.加密 var result = Base.encode('125中文'); //--> "MTI15Lit5paH" //2.解密 ...

  4. selenium + python 环境配置 (四)之启动Firefox

    火狐浏览器自身适配selenium   因此不需要再安装 直接代码启动: __author__ = 'admin' #作者 # -*- coding:utf-8 -*- # 建议所有都加编码 from ...

  5. eNSP下利用三层交换机实现VLAN间路由

    我们可以通过配置VLANif接口的方式来使交换机实现路由交换. 而VLANif接口是基于网络层的接口,可以配置ip地址 拓扑图如下

  6. 【leetcode算法-简单】26. 删除排序数组中的重复项

    [题目描述] 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完 ...

  7. 关于Django ModelForm渲染时间格式问题

    关于Django ModelForm渲染时间格式问题 直接定义DateTimeInput或者DateTimeFile是不行的,渲染在html页面中的仍然是Input text类型 解决办法:自定义小部 ...

  8. 其实每个行业都有各自的辛苦,好的程序员并不累,他们乐此不疲(见过太多在职位事业、人生方向上随转如流的人,累了疲乏了就去做别的事情了。必须有自己的坚守和立足的点,自我驱动,否则沦为在别人的体制制度中被驱赶一生)good

    作者:陈柯好链接:https://www.zhihu.com/question/39813913/answer/104275537来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  9. 开发人员需求能kill杀死其它阻塞自己的会话,测试发现需要alter system权限有风险

    模拟开发人员需求,可以杀死其它阻塞自己的会话1.能有查询阻塞会话确认的权限SQL> grant select on v_$session to testa;SQL> grant selec ...

  10. 方法引用(method reference)

    目录 方法引用(method reference) 1. 含义 2. 分类 3. 总结 方法引用(method reference) 1. 含义 方法引用实际上是 Lambda 表达式的一种语法糖. ...