一句话记住 FreeRTOS:”让单片机能像电脑一样同时做多件事,而且不乱套!”
FreeRTOS(Free Real-Time Operating System)是一款免费的、开源的实时操作系统(RTOS),专门为嵌入式系统(如STM32、ESP32等单片机)设计。它就像嵌入式设备的”小管家”,负责管理多个任务(Task),让它们有条不紊地运行,避免混乱。
FreeRTOS 的作用:
- 让多个任务”同时”运行(实际上是快速切换,看起来像同时运行)
- 确保关键任务优先执行(比如紧急报警比屏幕刷新更重要,也就是优先级)
- 避免代码”卡死”(如果一个任务出问题,其他任务还能继续运行)
FreeRTOS 的核心概念:

FreeRTOS 任务状态的概念:
- 就绪态( Ready):该任务在就绪列表中, 就绪的任务已经具备执行的能力,只等待调度器进行调度,新创建的任务会初始化为就绪态。
- 运行态(Running):该状态表明任务正在执行, 此时它占用处理器, FreeRTOS 调度器选择运行的永远是处于最高优先级的就绪态任务,当任务被运行的一刻,它的任务状态就变成了运行态。
- 阻塞态(Blocked): 如果任务当前正在等待某个时序或外部中断,我们就说这个任务处于阻塞状态,该任务不在就绪列表中。包含任务被挂起、 任务被延时、任务正在等待信号量、读写队列或者等待读写事件等。
- 挂起态(Suspended): 处于挂起态的任务对调度器而言是不可见的, 让一个任务进入挂起状态的唯一办法就是调用vTaskSuspend()函数;而把一个挂起状态的任务恢复的唯一途径就是调用vTaskResume()或vTaskResumeFromISR()函数,我们可以这么理解挂起态与阻塞态的区别,当任务有较长的时间不允许运行的时候,我们可以挂起任务,这样子调度器就不会管这个任务的任何信息,直到我们调用恢复任务的 API 函数;而任务处于阻塞态的时候,系统还需要判断阻塞态的任务是否超时,是否可以解除阻塞。
FreeRTOS 任务状态的变化 :

- ①创建任务→就绪态(Ready):任务创建完成后进入就绪态,表明任务已准备就绪,随时可以运行,只等待调度器进行调度。
- ②就绪态→运行态(Running):发生任务切换时, 就绪列表中最高优先级的任务被执行,从而进入运行态。
- ③运行态→就绪态:有更高优先级任务创建或者恢复后,会发生任务调度, 此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态, 依然在就绪列表中,等待最高优先级的任务运行完毕继续运行原来的任务(此处可以看做是 CPU使用权被更高优先级的任务抢占了)。
- ④运行态→阻塞态( Blocked):正在运行的任务发生阻塞(挂起、延时、 读信号量等待)时,该任务会从就绪列表中删除,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪列表中当前最高优先级任务。
- ⑤阻塞态→就绪态:阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态;如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换, 将该任务将再次转换任务状态,由就绪态变成运行态。
- ⑥⑦⑧就绪态、阻塞态、运行态→挂起态( Suspended):任务可以通过调用vTaskSuspend() API 函数都可以将处于任何状态的任务挂起,被挂起的任务得不到 CPU的使用权,也不会参与调度,除非它从挂起态中解除。
- ⑨挂起态→就绪态: 把 一 个 挂 起 状态 的 任 务 恢复的 唯 一 途 径 就 是调用 vTaskResume() 或 vTaskResumeFromISR() API 函数,如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务将再次转换任务状态,由就绪态变成运行态。
FreeRTOS 就绪列表的原理:
- 是一个链表数组, 每个成员都是一条链表,每个节点都是一个任务。
- 任务优先级默认为5,最大256
临界保护:
- 在临界保护区域的代码,不会被其它任务打断,能够确保程序正常执行完成,但是要记着在程序执行完之后,要退出临界保护
- 临界保护有四个函数,两种状态:
- 任务间的临界保护:taskENTER_CRITICAL和taskEXIT_CRITICAL,防止多个任务同时访问共享资源,通过 暂时禁止任务调度(但不关闭中断),确保当前任务独占资源。
- 中断间的临界保护:taskENTER_CRITICAL_FROM_ISR和taskEXIT_CRITICAL_FROM_ISR ,防止 中断服务程序(ISR)与任务 或 不同优先级中断 同时访问共享资源,通过 关闭中断 或 提升中断屏蔽优先级,确保当前代码段不被中断打断。
消息队列:
队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递)。任务和ISR(中断服务程序)统称为进程,任务与任务之间,或任务与ISR之间有时需要进行通讯或同步,称为进程间通信。
特点:

- 入队阻塞:队列满了,此时无法继续写入数据
- 出队阻塞:队列为空,此时无法读出数据
- 入队阻塞解除,有多个任务等待时,哪一个会进入就绪态:
- 优先级最高的任务
- 如果优先级相同,那等待时间最久的任务会进入就绪态
信号量:
信号量:是一种解决同步问题的机制,可以实现对共享资源的有序访问

按信号量的功能可分为:二值信号量、计数信号量、互斥信号量和递归互斥信号量
信号量的特点:

各种信号量的简介:
二值信号量: 特殊的队列,队列长度为 1,存在优先级翻转问题(低优先级先运行,高优先级的后运行)
计数信号量:基于二值信号量,可以有长度了
互斥信号量: 基本上和二值信号量完全一样,只是为了解决二值信号量的优先级翻转问题(优先级继承)

信号量与队列区别:

事件:
特点:

与队列和信号量的对比:

一个事件组中的所有事件位保存在一个EventBits_t类型的变量里,所以一个事件又称为一个“事件位”

简介:

参考链接:
- FreeRTOS-信号量介绍:STM32FreeRTOS信号量(STM32cube高效开发)_stm32 信号量-CSDN博客
- FreeRTOS-消息队列介绍:STM32FreeRTOS消息队列(STM32Cube高效开发)_stm32队列-CSDN博客
- FreeRTOS-任务通知介绍:STM32FreeRTOS任务通知(STM32cube高效开发)_xtaskgenericnotifyfromisr-CSDN博客
- FreeRTOS-事件组介绍:STM32FreeRTOS-事件组1(STM32Cube高效开发教程)_undefined symbol xeventgroupcreate-CSDN博客
- FreeRTOS-消息缓冲区和流缓冲区:FreeRTOS-消息缓冲区和流缓冲区(STM32Cubemx高效开发教程)_freertos流缓冲区-CSDN博客