FreeRTOS一天一个小知识之任务延时函数vTaskDelay

您所在的位置:网站首页 比赛开始最多延迟几分钟 FreeRTOS一天一个小知识之任务延时函数vTaskDelay

FreeRTOS一天一个小知识之任务延时函数vTaskDelay

2024-07-16 12:24:38| 来源: 网络整理| 查看: 265

  想必各位嵌入式工程师对于Delay延时函数再也熟悉不过了~

但对于各位刚入RTOS的小白来说,有操作系统的延时函数,真的和裸机中的延时函数一样吗?FreeRTOS的任务调度是怎么调度的?如何分配系统的CPU?

今天小编就带大家来扒一下FreeRTOS中的延时函数相对延时vTaskDelay函数,绝对延时vTaskDelayUntil函数。

从事嵌入式这一行的,想必大家在大学的时候一定上过C语言吧,上C语言的时候老师一定给大家写过Delay这个函数吧,给大家举个最简单的延时函数吧~

void Delay (u32 a)

{

   while(a--);

}

那同学们是否记得老师讲过这样一句话,“在以后项目开发中,千万不要用Delay这种死循环的方式来延时,最好用定时器来代替Delay延时函数“。

一般情况下,老师都会说过的对吧~

这是因为Dealy的延时,是通过CPU做循环的方式来延时,CPU在延时中是做不了其他东西的,大大浪费了CPU的效率!而且非常危险!

所以大家在裸机中如果要需要很长时间延时的话,建议用定时器来延时。但今天的重点不是裸机的延时函数,而是有操作系统的延时函数。

/*********************************************************************************************************************************************************************************/

刚开始学习FreeRTOS的时候看到FreeRTOS的API延时函数,不竟在想,实时操作系统不是讲究的是实时性吗,怎么也会有这种延时函数!给位大佬有没有共同的感受!

后来深入了解FreeRTOS之后,才发现,原来这延时函数写的这么巧妙!

我们先来看一下 vTaskDelay的源码。这是FreeRTOS中的延时API函数。

void vTaskDelay( const TickType_t xTicksToDelay )     {     BaseType_t xAlreadyYielded = pdFALSE;         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();         }     }

 参数:const TickType_t xTicksToDelay 这是输入你要延时的时间

我们看源码我们会发现, vTaskDelay中竟然有挂机函数vTaskSuspendAll();  和恢复函数xTaskResumeAll();

原来在任务中调用延时函数,只是把任务挂起了,等延时时间到,在把任务恢复。

举个例子:

我这边有两个TASK,TASK1和TASK2;

void Task1( void * pvParameters ) {          uint8_t i=0;          while(1)     {                  printf("TASK1 RUNNING%d\r\n",i);         GPIO_SetBits(GPIOC,GPIO_Pin_2);             vTaskDelay(500);         GPIO_ResetBits(GPIOC,GPIO_Pin_2);             i++;                  vTaskDelay(500);          } }     void Task2( void * pvParameters ) {         uint8_t j=0;         while(1)         {             j++;             GPIO_ResetBits(GPIOC,GPIO_Pin_3);                 vTaskDelay(200);             GPIO_SetBits(GPIOC,GPIO_Pin_3);                 vTaskDelay(800);             printf("TASK2 RUNNING%d\r\n",j);                      }

}

FreeRTOS这个任务执行是这样的。首先TASK1创建,然后在创建TASK2

TASK先执行, 执行到GPIO_SetBits(GPIOC,GPIO_Pin_2);    下一句vTaskDelay(500);   延时500ms,其实就是任务挂起500ms,CPU此时不会执行TASK的任务,去执行

处于就绪态的TASK2,   当TASK2的GPIO_ResetBits(GPIOC,GPIO_Pin_3);    执行好了之后执行下一条 vTaskDelay(200);此时TASK1延时500ms,TASK延时200ms。

这时候FreeRTOS是没有执行处于就绪态的任务的,只有执行空闲任务 。此时由于TASK2是延时200ms,比TASK2延时的500ms要快,所以TASK2比TASK1更早进入

就绪态,此时CPU执行  GPIO_SetBits(GPIOC,GPIO_Pin_3);    这一语句,执行好了之后TASK2又延时800ms,进入挂起态。当TASK1延时500ms到,TASK1进入就绪态,

执行GPIO_ResetBits(GPIOC,GPIO_Pin_2);     i++;语句,执行完之后,TASK1又进入500ms的延时,进入挂起态~

所以在FreeRTOS中的延时函数,只是任务挂起和任务恢复而已,就像创建二值信号量,其实就是创建队列~

学习操作系统本来就是一件枯燥且乏味的事情~共勉

绝对延时vTaskDelayUntil函数下次又机会在讲。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭