延时函数

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. .Net Core 定时器Quartz

    最近因为项目需要用到了Quartz,下面简单记录一下. 一.首先需要安装Quartz. 二.定义一个执行的Job类,实现IJob接口,接口有一个方法Execute,用来执行定时任务的实现内容. pub ...

  2. Docker 容器的资源限制 cgroup(九)

    目录 一.cgroup简介 二.CPU资源配额控制 1.CPU份额控制 2.CPU周期控制 3.CPU core控制 4.CPU配额控制参数的混合使用 二.对内存的限额 三.对 Block IO 的限 ...

  3. 三节课MINI计划第五周

    一.任务及干货 二.作品 (一)小组分工 (二)社群运营方案

  4. linux中查看磁盘容量的常用操作

    linux中查看磁盘容量常用操作 实验室有GPU集群,用户跑数据时候跑着跑着会出现集群挂掉的问题,原因就是,在跑数据时,用户上传文件,数据集,系统产生缓存等一系列操作,消耗了集群空间,师兄让我清理下服 ...

  5. 高阶函数 filter map reduce

    const app=new Vue({ el:'#app', data:{ books:[{ id:1, name:"算法导论", data: '2006-1', price:39 ...

  6. openlayers集成到vue开发

    openlayer初步加载地图 vue项目搭好后,直接用node js安装ol, 安装好后可以看看安装的版本:我用的是5..2的版本 然后看官网相对应版本的文档,都是英文文档; 官方文档:    ht ...

  7. PowerShell->>获取本地计算机的用户组和组成员

    获取本地计算机的用户组和组成员 function Get-LocalGroups() { net localgroup | ?{ $_ -match "^\*.*" } | %{ ...

  8. MapReduce的输入文件是两个

    [学习笔记] 1.对于MapReduce程序,如何输入文件是两个文件? 这一小节,我们将继续第一章大数据入门的HelloWorld例子做进一步的研究.这里,我们研究如何输入文件是两个文件.packag ...

  9. 4.JVM 实战操作

    1.1 JVM参数 1.1.1 标准参数 -version -help -server -cp 1.1.2 -X参数 非标准参数,也就是在JDK各个版本中可能会变动 -Xint 解释执行 -Xcomp ...

  10. 20191011-构建我们公司自己的自动化接口测试框架-ProVar模块

    ProVar模块主要定义测试数据所在目录,以及定义变量和测试数据excel里面的column对应这样后续在进行excel操作的时候直接使用变量即可进行操作,后期excel的column有增删的时候,修 ...