想必各位嵌入式工程师对于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函数下次又机会在讲。

FreeRTOS一天一个小知识之任务延时函数vTaskDelay相关推荐

  1. [一天一个小知识]instanceof

    instanceof是Java.php的一个二元操作符(运算符),和==,>,<是同一类东西.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是判断其左边对象是否为其右边类的实 ...

  2. 一天一个小知识-- kt中的object关键字

  3. 一天一个小知识:KT高阶函数

    让我们从匿名函数聊起 我们听说过有匿名类,那作为一等公民的函数就也会有匿名函数 什么是一等公民? 我们知道Java的一等公民是类,就连一个普通的程序入口也要用类包一下.而kotlin中除了类是一等公民 ...

  4. python中函数的参数_Python小知识-Python中的函数参数(基础篇)

    0 总述 这个题目分为2篇,第一篇基本上是概念以及实例,有个相对系统的认识,第二篇想写的深入一些,不同参数类型的区别以及和c/c++的函数参数对比下异同-下面开始是第一篇的内容啦- Python中的函 ...

  5. 编程小知识之 Lua split 函数

    本文简单介绍了如何在 Lua 中实现 split 函数 Lua 的标准库并没有提供字符串的 split 函数,不过自己实现一下也并不困难,网上其实也早有了很多实现版本: 一个 gist 实现 SO 上 ...

  6. Kotlin小知识之高阶函数

    文章目录 高阶函数 定义高阶函数 函数类型 高阶函数示例 内联函数 内联函数的作用 内联函数的用法 noinline与crossinline 高阶函数 定义高阶函数 高阶函数和Lambda的关系是密不 ...

  7. STM32单片机初学者编程之常用小程序--GPIO配置延时函数

    声明:本专题系列的博文主要是用于个人学习以及后续查阅调用,由于是这方面的初学者,所以写的比较浅陋,有喜欢的朋友可以一起学习,编程大神们请略过...... 1.以一个GPIO的初始化程序为例,以下是GP ...

  8. fafts sd卡开启中断_使用FreeRTOS在SD卡驱动使用非系统延时导致上电重启不工作的情况...

    一.问题描述 在一个使用FreeRTOS的工程中,只做了SD卡的驱动,由于RTOS使用了Systick,故非系统延时函数使用的是 DWT中的时钟周期(CYCCNT)计数功能,但是在SD卡驱动中使用了这 ...

  9. 【11】FreeRTOS的延时函数

    目录 1.延时函数-介绍 2.相对延时函数-解析 2.1函数`prvAddCurrentTaskToDelayedList`-解析 2.3滴答定时器中断服务函数`xPortSysTickHandler ...

最新文章

  1. python现在好找工作吗-转行学Python好找工作吗?
  2. 写出现代计算机网络的三个方面的应用,《计算机应用基础》统考模拟试题一及参考答案0...
  3. 50代码HTML5 Canvas 3D 编辑器优雅搞定
  4. c语言与python的区别
  5. 使用SQL Server Analysis Services Tabular Model建立分析模型
  6. java jmap 分析_利用java虚拟机的工具jmap分析java内存情况
  7. Mysql学习总结(8)——MySql基本查询、连接查询、子查询、正则表达查询讲解...
  8. nginx服务无法启动,启动时报错1067以外终止
  9. Qt笔记-Qt中Json存二进制文件并读取文件(QJsonObject、QJsonArray、QJsonDocument的使用)
  10. windows文件(.txt,.h,.cpp等等)中的中文在ubuntu下乱码的解决方法
  11. 参与社团活动的意义_大学参加社团活动有意义吗?
  12. 【模拟电子技术Analog Electronics Technology 14】——集成运放中的单元电路 之 集成运放的输入级:长尾式差放各种接法的参数分析
  13. 2006年~2011年记事简要
  14. 软件 测试试用期转正申请,软件工程师试用期工作总结及转正申请
  15. 2019年全国/全球马拉松比赛日程
  16. Ubuntu18.04 安装花生壳并使用
  17. Spark面试题及其答案
  18. 新品成熟EMR源码电子病历系统软件NET网络版CS可用带数据库全文档
  19. Python使用Win32和天行机器人API实现微信自动聊天机器人(自动敷衍机器人)
  20. 智安新闻丨乐山西部AI算谷正式投运,与智安网络成功签署战略合作协议!

热门文章

  1. linux透明防火墙接入fte 300 网络的问题
  2. 电销系统如何处理客户回电
  3. 高效能研发体系构建方案
  4. Corejava知识点
  5. 今日分享|闪魔钢化膜5.8又来了/kn95口罩50个29.9/奥利司他胶囊7粒17.9/加拿大芬尼湾矿泉水/耐克同款/面膜等...
  6. CCP协议学习《一》
  7. vue下拉组件_高度动态的Vue下拉组件
  8. 新旧年交替的“投基”策略
  9. PCIe和NVMe SSD初始化过程简介
  10. flink配置historyserver