目录
今天开个新坑----FreeRTOS
简单介绍
FreeRTOS是一个轻量级的实时操作系统(RTOS),专为微控制器和小型处理器设计,广泛应用于嵌入式系统领域。它提供了任务管理、时间管理、互斥量、信号量等基本的实时操作系统功能,支持多任务处理,使得开发者能够在单一处理器上同时运行多个任务。
其核心特点:
- 轻量级和高效:FreeRTOS占用的内存非常小,适合资源受限的嵌入式系统。
- 跨平台支持:支持多种微控制器架构,包括ARM Cortex-M、AVR、PIC32等。
- 可配置性:提供灵活的配置选项,允许开发者根据需求调整系统功能。
- 丰富的API:提供了丰富的API函数,便于实现任务管理、同步机制、时间管理等功
FreeRTOS基础知识
任务调度
FreeRTOS的任务调度是其核心功能之一,它允许多个任务在单个处理器上并发执行。任务调度器控制哪个任务应当在何时运行,以及运行多长时间,从而实现对处理器时间的高效管理。
抢占式调度**:**
在FreeRTOS中,每个任务都被分配一个优先级,优先级的数值越高,任务获得CPU时间的优先权就越大。(我们采用的是硬件优先级,就是从0-31,总共32位。在FreeRTOS中任务设置的数值越大,优先级越高)。
上下文切换:当操作系统决定将CPU从一个任务切换到另一个任务时,需要保存当前任务的状态(上下文)并加载新任务的状态,这个过程称为上下文切换。
中断:抢占通常是通过硬件中断实现的。当一个高优先级任务需要执行时,操作系统会接收到一个中断信号,触发当前任务的抢占。
举例说明:
假设有一个简化的操作系统,其中运行着三个任务:任务A、任务B和任务C,它们的优先级依次降低。
- 开始时:任务A首先获得CPU,开始执行。
- 任务B到来 :在任务A执行期间,更高优先级的任务B到达。操作系统接收到任务B的请求,并决定抢占任务A,将CPU分配给任务B。
- 此时,系统会保存任务A的当前状态(如寄存器值、程序计数器等),这是上下文切换的一部分。
- 接着,系统加载任务B的上下文,并开始执行任务B。
- 任务C到来:假设在任务B执行期间,任务C也到来了。但因为任务C的优先级低于任务B,所以任务B继续执行,不会被任务C抢占。
- 任务B完成 :任务B执行完毕后,系统再次进行上下文切换,此时会检查等待执行的任务中优先级最高的任务。
- 因为任务A的优先级高于任务C,所以系统会恢复任务A的上下文,并继续执行任务A。
- 任务A完成后:任务A完成后,系统再次进行上下文切换,开始执行剩余的任务C。
时间片调度
同等优先级的情况下,可以有多个任务,那么就有了时间片调度。在具有相同优先级的任务之间使用时间片调度(会在每一次系统时钟节拍到的时候切换任务)。时间片调度的目标是保证具有相同优先级的任务获得公平的处理器时间分配。
时间片的长度通常由系统的时钟滴答(Tick)率决定,一个时间片是滴答定时器中断周期(是可以设置的)。当一个进程的时间片用完时,系统会保存当前进程的状态,然后将CPU分配给下一个进程。
举例说明
假设有三个进程:进程A、进程B和进程C,它们几乎同时到达就绪队列,等待CPU执行。操作系统采用时间片调度策略,每个进程被分配一个时间片长度为10毫秒。
- 进程A开始执行:首先,进程A获得第一个时间片(10毫秒),开始执行。
- 进程A的时间片用完:10毫秒后,不管进程A是否完成,它的时间片已经用完。系统执行上下文切换,保存进程A的当前状态。
- 进程B获得CPU:接着,系统将CPU分配给进程B,进程B开始使用它的10毫秒时间片执行。
- 进程B的时间片用完:类似地,进程B的时间片用完后,系统再次进行上下文切换,保存进程B的状态。
- 进程C获得CPU:然后,进程C获得CPU,开始执行它的时间片。
- 循环继续:进程C的时间片用完后,如果所有进程仍需要CPU时间,系统会再次从进程A开始,继续这个循环过程。
补充:任务中没有用完的时间片不会再使用,下次执行的时候还是按照一个时间片的时钟节拍运行
任务状态
FreeRTOS中4种任务状态
**运行态:**正在执行的任务,该任务就处于运行态,注意在STM32中,同一时间仅一个任务处于运行态
**就绪态:**如果该任务已经能够被执行,但当前还未被执行,那么该任务处于就绪态
**阻塞态:**如果一个任务因延时或等待外部事件发生,那么这个任务就处于阻塞态
**挂起态:**类似暂停,调用函数 vTaskSuspend() 进入挂起态,需要调用解挂函数vTaskResume()
才可以进入就绪态
四种任务状态转换图

只有就绪态可转变成运行态。
其他状态的任务想运行,必须先转变成就绪态。
任务状态列表
就绪列表(Ready List)
就绪列表包含所有准备好执行但正在等待CPU分配的进程。这些进程已经获得了除CPU之外的所有必要资源,并且随时可以开始执行。
调度器总是在所有处于就绪列表的任务中,选择具有最高优先级的任务来执行
假设有三个进程A、B和C,它们都已完成初始化并准备执行。如果只有一个CPU可用,那么在任何给定时刻,只有一个进程可以执行,而其他进程则被放入就绪列表中,等待调度程序分配CPU资源。
阻塞列表(Blocked List 或 Waiting List)
阻塞列表包含那些因为某种原因(如等待I/O操作完成、等待信号量或其他同步事件)而暂停执行的进程。处于阻塞状态的进程不能执行,直到其等待的事件发生。
进程D发出了一个读取硬盘的I/O请求。由于I/O操作需要时间完成,进程D将被移入阻塞列表,并处于等待状态,直到数据读取完成。在这段时间里,CPU可以被分配给就绪列表中的其他进程。
挂起列表(Suspended List)
挂起列表包含那些被暂时挂起(冻结)的进程。挂起的原因可能是系统资源不足、用户请求、或进程正在被调试。挂起的进程既不会执行,也不会被调度,直到它们被重新激活。
假设系统内存资源紧张,操作系统可能决定挂起一些低优先级或当前不活跃的进程,将它们移入挂起列表,并释放它们占用的内存资源。当资源变得可用时,这些进程可以被重新激活,移回就绪列表,等待执行。