2、FreeRTOS - 任务、任务管理、任务状态

任务,通俗点讲其实就是函数(任务函数)。任务是由任务创建 API 函数创建,有动态和静态两种方式创建方式,是 FreeRTOS 最基本的调度单位。

RTOS 的任务管理是什么?

RTOS 的核心就是任务管理,有多任务管理系统,相比于裸机,最大的区别是多了任务这种东西,大多数学习 RTOS 系统的人,主要就是为了使用 RTOS 的多任务处理功能,即多任务系统。

裸机开发的时候一般是在主函数 main 里使用一个大循环(如 while)不断的完成所有工作,循环中再调用需要的功能函数,实现我们想要的功能,任务也是同理会用到循环完成工作(如 while 无限循环,也可以不用,具体怎么使用看实际情况),不同的是,有了任务这种东西以后,我们就可以把不同类别的功能函数区分开,分别放到不同的任务函数中去循环执行,不会再把全部功能都整合到一个大循环里面(一旦项目很大,裸机开发的程序运行效果就很差,不同功能间实现的时间间隔会被放大,都是排队等着轮流执行,不管你这个程序现在有多紧急,没轮到你就只能等着,实时性很差。一般在大工程项目中就要加入 RTOS,小工程就没必要)。任务其实就是函数(称为任务函数),不同的任务函数之间互不干涉,完成各自的工作。

我们做项目时,要实现的功能肯定不止一个,会同时存在多个任务,这些任务都是统一由任务调度器管理(任务调度器有相应的开启函数和关闭函数),它的作用就是不断的切换任务,应该轮到哪个任务运行,它就会帮你自动切换过去,这个不同任务之间的切换过程称为任务调度

什么情况下会进行任务调度?

①开启了任务调度器 ②有任务处于就绪态,位于就绪列表。满足条件后,此时任务调度器就会开始调度就绪列表的任务(会选择最高优先级的任务执行)

调度的方式有:

1、时间片调度

 一般是同优先级的任务之间的调度,每过一个心跳周期,任务调度器就会调度一次,切换另一个同级任务(每个任务只执行一个心跳周期,交替进行)

2、优先级调度

一般是不同优先级的任务之间的调度,高优先级的任务永远占据 CPU 资源,低优先级永远等不到 CPU 资源,除非在高优先级任务中调用 FreeRTOS 的延时函数,才能暂时挂起高优先级任务去运行低优先级任务


任务的运行状态

FreeRTOS 系统中的每一任务都有多种运行状态,通常分为以下四种:

1、就绪态(Ready):在等待被调度器调度的任务,任务必须是就绪态才能被任务调度器调度。新创建的任务会初始化为就绪态。

2、运行态(Running):是被调度的任务,正在运行中的任务,此时正占用着 CPU。

3、阻塞态(Blocked):任务运行的过程中,需要等待某个事件发生后才能继续运行(例如,任务想要向队列里发送消息,如果队列满了还想发送,任务就会进入阻塞,等待队列出现空位,队列出现空位了任务就退出阻塞,进入就绪态),在这个等待过程不占用 CPU,等到想要的结果后会重新进入就绪态。这个等待过程就是阻塞。

4、挂起态(Suspended):任务进入挂起态的唯一办法就是调用 vTaskSuspend 函数,相比阻塞态,这是任务主动调用了 vTaskSuspend 函数,而不是需要等待什么事件发生,想要退出挂起也只能通过其他任务调用挂起状态的任务恢复函数 vTaskResume 或 vTaskResumeFromISR 唤醒挂起态任务。

阻塞和挂起都是退出运行态,不进入就绪态(不在就绪列表中),无法被调度执行。两者的区别:阻塞是被动,挂起是主动。

任务的运行状态的切换

FreeRTOS 系统中的任务有多个状态,不同的状态之间的转换关系如下:

c0ea874eea9f46afaf21e14eed430479.png

1、任务挂起函数

使用前需将宏 INCLUDE_vTaskSuspend 配置为 1(所有的宏都在 FreeRTOSConfig.h 文件里)

函数

vTaskSuspend (待挂起任务的任务句柄 / NULL)

参数为 NULL 时,则挂起任务自身

功能

挂起任务。挂起任务就类似暂停,是可以恢复的,被挂起的任务绝不会得到 CPU 的使用权,不管该任务具有什么优先级,也不会参与调度,它相对于调度器而言是不可见的,除非它从挂起态中解除

函数

vTaskSuspendAll ( )

功能

这个函数就是比较有意思的,将所有的任务都挂起,其实源码很简单也很有意思, 不管三七二十一将调度器锁定,并且这个函数是可以进行嵌套的,说白了挂起所有任务其实本质就是挂起任务调度器。调度器被挂起后则不能进行上下文切换,但是中断还是使能的。当调度器被挂起的时候,如果有中断需要进行上下文切换,那么这个任务将会被挂起,在调度 器恢复之后才执行切换任务

(本质是挂起任务调度器)

2、任务恢复函数

使用前需将宏 INCLUDE_vTaskSuspend 配置为 1

函数

vTaskResume (待恢复任务的任务句柄)

功能

恢复被挂起的任务。任务恢复就是让挂起的任务重新进入就绪状态,恢复的任务会保留挂起前的状态信息,在恢复的时候根据挂 起时的状态继续运行。如果被恢复任务在所有就绪态任务中,处于最高优先级列表的第一 位,那么系统将进行任务上下文的切换

函数

vTaskResumeAll ( )

功能

恢复任务调度器

使用前需要将宏 INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 配置为1

函数

vTaskResumeFromISR (待恢复任务的任务句柄)

功能

在中断中恢复被挂起的任务(带有 FromISR 后缀的 API 函数都是专门用来针对中断函数的)

返回值

(该函数是有返回值的)

返回 pdTURE,代表该任务恢复后需要进行任务切换,此时要用户自己手动调用任务切换的 API 函数来进行任务切换;

返回 pdFALSE,代表该任务恢复后不需要进行任务切换;

注意,在中断服务函数中要调用 FreeRTOS 的 API 函数时,该中断的优先级不能高于 FreeRTOS 所管理的最高优先级,一般默认 FreeRTOS 能管理的优先级范围是 5~15,所以中断优先级不能在 0~4 之间(在配置 NVIC 给中断通道分配优先级时,不能分配 0~4 的优先级)

9d087c571490478c886c72c348b62381.png

3、任务延时函数

函数

vTaskDelay ( )

功能

vTaskDelay ( ) 在我们任务中用得非常之多,每个任务都必须是死循环,所以高优先级任务必须要有阻塞的情况,否则低优先级的任务就无法被运行了。要想使用 FreeRTOS 中的 vTaskDelay() 函数必须在 FreeRTOSConfig.h 中把 INCLUDE_vTaskDelay 定义为 1 来使能

4、绝对延时函数

函数

vTaskDelayUntil ( )

功能

在 FreeRTOS 中,除了相对延时函数,还有绝对延时函数 vTaskDelayUntil(),这个绝对延时常用于较精确的周期运行任务,比如我有一个任务,希望它以固定频率定期执行,而不受外部的影响,任务从上一次运行开始到下一次运行开始的时间间隔是绝对的,而不是相对的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值