IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【FreeRTOS】03 任务的运行、就绪、阻塞、挂起 -> 正文阅读

[嵌入式]【FreeRTOS】03 任务的运行、就绪、阻塞、挂起

讲到操作系统的任务,就不得不提任务的状态和切换,这是操作系统的最核心功能。本节将会重点讲解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的执行权进入运行态,其他正在执行的任务会变成就绪态;只有高优先级的任务被阻塞时,低优先级的任务才可能进入运行态。

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

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

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:04:54  更:2022-05-10 12:05:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 13:01:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码