讲到操作系统的任务,就不得不提任务的状态和切换,这是操作系统的最核心功能。本节将会重点讲解freeRTOS任务的几种状态——运行、就绪、阻塞、挂起。

1)FreeRTOS任务的状态

freeRTOS任务的状态有四种:运行、就绪、阻塞、挂起。

运行态(runnnig):当任务正在运行,此时的状态被称为运行态,即CPU的使用权被这个任务占用;

挂起态(suspended):任务被暂时停止,通过调用挂起函数(vTaskSuspend())可以把指定任务挂起,任务挂起后暂时不会运行,只有调用恢复函数(xTaskResume())才可以退出挂起状态;

阻塞态(blocked):任务在等待信号量、消息队列、事件标准组、系统延时时,被称为阻塞态,如果等待的事件到了,就会自动退出阻塞态,准备运行;

就绪态(ready):任务已经具备了运行条件(没有被挂起或阻塞),但是又更高优先级或同优先级的任务正在运行,所以需要等待的状态。

一般任务创建完成后,进入就绪态;处于就绪态的任务,如果没有更高优先级或同优先级的任务正在运行,它会自动进入运行态;如果有更高优先级的任务要运行,或者同优先级的任务要轮流运行,它会从运行态返回到就绪态;如果任务需要等待信号量、消息队列、事件标准组等事件,或者任务自己进入了系统延时,则会进入阻塞态;当等待的事件达到后,任务又会进入就绪态。

任务被调用vTaskSuspend()函数会进入挂起状态,暂时不会运行,只有调用xTaskResume()函数,任务才会退出挂起状态,进入就绪态。

下图表示了freeRTOS任务状态的变化图:

2)任务的挂起实例

任务的挂起状态比较简单,我们先来编写一个实例,测试任务的挂起和恢复状态。

这个例子中,我们创建三个任务,起始时三个任务都在运行;之后我们挂起Task02和Task03;最后再恢复Task02和Task03;观察他们的状态。

使用的工程和第一节的一样,创建两个用户Task02、Task03任务,系统会自动创建一个default任务,这样我们就有了三个任务。

另外,添加串口作为打印输出,以便于观察现象。在cubemx建立工程时,添加串口的初始化:

生成keil工程,在usart.c文件中添加如下代码,进行printf函数和的重定向,这样,我们就可以使用C语言的printf函数进行串口打印了:

接下来我们编写测试和代码,在Task02和Task03任务中,添加打印函数,这样我们可以观察到任务是否在运行:

然后,在default任务中,添加挂起和恢复任务的函数,如下:

作用是延时5s后挂起Task02,再延时1s后挂起Task03;然后延时1s后恢复Task02,再延时1s恢复Task03:

连接串口,使用串口调试助手监测打印输出。编译下载运行,结果如下:

可以看到Task02挂起之后,它没有打印输出了,而Task03还在运行;当Task03也被挂起后,两个任务就都没有打印输出了;直到Task02恢复,Task02开始又有打印输出;Task03恢复后,Task03也恢复了输出。

3)任务的就绪、运行、阻塞实例

接下来我们来试验任务的就绪、运行、阻塞的例子。

在这个例子中,我们用高优先级的任务占用一段CPU时间;那么它在运行时,其他任务是不能运行的,最多只能在就绪态;只有高优先级的任务自己放弃CPU,进入阻塞态时,其他就绪态的任务才能运行。

仍然使用上一个例子的工程,在keil工程中修改代码。

先修改三个任务的优先级:default任务最高,Task02次之,Task03最低:

编写三个任务的执行代码:

以高优先级的default任务为例讲解,在占用CPU时,打印正在运行的提示;占用5s后,打印进入阻塞态的提示,然后利用系统延时函数阻塞自己,放弃CPU的执行权5s;周而复始:

需注意这里用的HAL_Delay()函数和osDelay()函数的区别:

HAL_Delay()函数是cubemx生成的延时函数,它会占用CPU的执行时间,一直等在此处,直到延时时间到,才向后执行;相当于这段延时里占用了CPU;

而osDelay()函数是freeRTOS的函数,它在执行到这里时,会使得本任务放弃CPU的执行权,从运行态变到阻塞态,直到延时的时间到,本任务会回到就绪态;在阻塞态时,它是放弃了CPU的占有权的,其他就绪态的任务可以在此时间段内执行。

Task02、Task03内部的代码和default任务基本一样,只是延时都改成了2s和1s:

编译下载运行,查看串口调试助手的打印信息:

可以看到,起始时,default任务占用了CPU,其他任务没有执行;直到5s后,default调用了osDelay()函数,自己阻塞了自己,此时,处于就绪态的其他较低优先级的任务才可能运行;可以看到,之后Task02开始运行,又过了2s后,中优先级的Task02也自己阻塞了自己,Task03才有机会运行。

之后在Task02第二次运行时,它还没有执行到阻塞自己,default任务的阻塞时间就到了;高优先级的default任务直接抢占了CPU的执行权,Task02被挤到就绪态;直到5s后,default再次阻塞自己时,Task02才继续恢复执行。

从这个例子可以看出,高优先级的任务需要运行时,会直接抢占CPU的执行权进入运行态,其他正在执行的任务会变成就绪态;只有高优先级的任务被阻塞时,低优先级的任务才可能进入运行态。

好了,本节的内容就到这里了。

如果觉得有用可以关注作者微信号“小白白学电子”,在公众号可以找到代码和资料下载地址:

【FreeRTOS】03 任务的运行、就绪、阻塞、挂起相关推荐

  1. 2.1.2 操作系统之进程的状态(运行、就绪、阻塞、创建、终止)及转换(就绪->运行、运行->就绪、运行->阻塞、阻塞->就绪)

    1 思维导图总览 五种状态: 创建态.终止态.就绪态.运行态.阻塞态. 2 进程的状态 2.1 三种基本状态(就绪.运行.阻塞) 三种基本的状态: (1)运行态:占有CPU,并在CPU上运行: (2) ...

  2. 线程五种状态(新建、就绪、运行、阻塞、死亡)

    线程的5种状态: 每个 Java 程序都有一个缺省的主线程,对于 Java 应用程序,主线程是 main()方法执行的线索: 对于 Applet 程序,主线程是指挥浏览器加载并执行 Java Appl ...

  3. 2.1.2 操作系统之进程的状态(运行、就绪、阻塞、创建、终止)及转换(就绪-运行、运行-就绪、运行-阻塞、阻塞-就绪)

    文章目录 1.思维导图总览 2.进程的状态 (1)三种基本状态(就绪.运行.阻塞) (2)创建态和结束态 3.进程状态之间的转换 1.思维导图总览 2.进程的状态 (1)三种基本状态(就绪.运行.阻塞 ...

  4. 线程有哪些状态?创建、就绪、运行、阻塞和死亡

    线程有哪些状态? 线程通常都有五种状态,创建.就绪.运行.阻塞和死亡. 创建状态.在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态. 就绪状态.当调用了线程对象的start方法之 ...

  5. 08-操作系统之进程的状态(运行、就绪、阻塞、创建、终止)及转换(就绪->运行、运行->就绪、运行->阻塞、阻塞->就绪)

    目录 1.思维导图总览 2.进程的状态 2.1.三种基本状态(就绪.运行.阻塞) 2.2.创建态和结束态 3.进程状态之间的转换 1.思维导图总览 2.进程的状态 2.1.三种基本状态(就绪.运行.阻 ...

  6. select/poll原理(阻塞挂起) 正常(阻塞轮询)

    遍历所有的fd, 如果没好(不就绪),加入(对应fd)等待队列,如果所有fd都没好(不就绪),挂起线程(schedule_timeout) 直到就绪唤醒或超时,再次遍历并退出 static int d ...

  7. 在Amazon FreeRTOS V10中使用运行时统计信息

    在MCU on Eclipse网站上看到Erich Styger在8月2日发的博文,一篇关于在Amazon FreeRTOS V10中使用运行时统计信息的文章,本人觉得很有启发,特将其翻译过来以备参考 ...

  8. FreeRTOS 中 RISC-V-Qemu-virt_GCC 的 运行流程 的异常分析

    在 RISC-V-Reader-Chinese-v2p1.pdf 中RISC-V 中实现精确例外:保证异常之前的所有指令都完整地执行了,而后续的指令都没有开始执行(或等同于没有执行) 所有 RISC- ...

  9. VINS学习03——使用Realense_D435i运行Vins_Fusion

    1. 简介 上一篇跑了一下VINS_Fusion自带的demo,用的是几个常用的开源数据集,这篇文章主要是将VINS_Fusion用在自己的实验室设备上,在进行前期参数标定.config文件修改.精度 ...

最新文章

  1. VC2008 忽然无法调试DLL的解决方法
  2. 将vim打造成IDE编程环境
  3. 不想写脚本清理 mongodb 中的垃圾数据,ttlIndex 能帮到你!
  4. Java7任务并行执行神器:ForkJoin框架
  5. [项目经验]玩转开源项目
  6. java设置等待锁的时间_java的锁池和等待池
  7. vue中warning_vue项目运行提示Warnings while compiling.警告的解决方法
  8. Linux一些基本概念
  9. SMT操作手册V1.0 模板
  10. 常见蛋白质种类_生活中常见食物的营养学分类,以及不同食物的蛋白质含量
  11. 你真的知道如何选择内存条吗?
  12. 过去式与过去分词的用法与区别
  13. matlab特征值归一化,如何用matlab将特征向量归一化呢?
  14. 敏捷.敏捷项目管理V2.Jim Highsmith
  15. UniRx_UniTask_学习记录_3.1_Subject
  16. 家庭网络文件共享的几种方式
  17. 安防无战事:一场10213亿元的误会 1
  18. 上帝视角观看黑客攻防战
  19. 第二十六篇:USB3.0高带宽ISO(48KBytes/125us)实战
  20. 面试官:你先回去等通知吧!这个 Java 岗位我还有机会吗?

热门文章

  1. NPL程序设计语言,CNN,RNN,LSTM ,spark和hadoop的区别,云计算,kubeflow
  2. FFmpeg Filter简单使用
  3. 改脸型先要了解脸型结构
  4. java中指数函数的使用方法图解,基本初等函数 指数函数 代码篇
  5. 任务宝,聚合任务网站数据接口和APP
  6. 机器学习:批量梯度下降法(线性回归中的使用)
  7. Unity动画☀️动画帧事件
  8. php indexdb,浏览器端数据库存储方案的整理 -- indexDB 和 localStorage
  9. 利用TeamViewer实现唤醒远程电脑一例方法
  10. 基于c语言的简单的mysql数据库操作