
🎬 渡水无言 :个人主页渡水无言
❄专栏传送门 : 《linux专栏》《嵌入式linux驱动开发》《freertos专栏》
⭐️流水不争先,争的是滔滔不绝
📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生
| 省级优秀毕业生获得者 | csdn新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生
在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连

目录
[1.1 前后台系统:最基础的裸机架构](#1.1 前后台系统:最基础的裸机架构)
[1.2 时间片轮询系统:裸机的 "进阶版"](#1.2 时间片轮询系统:裸机的 “进阶版”)
[3.1. 裸机系统:当简单和极致性能是首选](#3.1. 裸机系统:当简单和极致性能是首选)
[3.2. FreeRTOS:当复杂度和可维护性成为刚需](#3.2. FreeRTOS:当复杂度和可维护性成为刚需)
前言
本期博客我们讲解一下为什么使用rtos以及其核心功能,并和裸机进行区别。
一、裸机系统
1.1 前后台系统:最基础的裸机架构
在没有 RTOS 的裸机开发中,典型的程序结构是一个大循环 while(1),所有任务都在这个循环里顺序执行:
#include <stdint.h>
// 全局标志位
uint8_t flag1 = 0, flag2 = 0;
// 硬件初始化
void HardWareInit(void) {
// 初始化GPIO、中断、定时器等硬件
}
// 任务函数
void run_task_1(void) { /* 任务1具体逻辑 */ }
void run_task_2(void) { /* 任务2具体逻辑 */ }
void run_task_3(void) { /* 任务3具体逻辑 */ }
// 中断服务程序1(前台)
void ISR1(void) {
flag1 = 1; // 仅置位标志位,不执行耗时操作
}
// 中断服务程序2(前台)
void ISR2(void) {
flag2 = 1; // 仅置位标志位
}
int main(void)
{
HardWareInit(); /* 硬件相关初始化 */
while(1)
{
if(flag1)
{
run_task_1(); /* 执行任务1 */
flag1 = 0;
}
if(flag2)
{
run_task_2(); /* 执行任务2 */
flag2 = 0;
}
run_task_3(); /* 持续执行任务3 */
}
}
这种架构的优势是简单易实现、任务不丢失 ,但致命问题是实时性不可控:
-
若
run_task_3执行耗时 1 分钟,即使中断 1 触发,run_task_1也需等任务 3 执行完毕才能响应; -
若将
run_task_1直接放入中断执行,又违背 "中断快进快出" 原则 ------ 耗时 1 分钟的中断会阻塞低优先级中断,甚至导致中断丢失。
1.2 时间片轮询系统:裸机的 "进阶版"
时间片轮询是裸机开发的优化方案:以定时器为核心,按预设周期轮询执行不同任务,避免 CPU 空转,是裸机中性价比极高的实现方式。
#include <stdint.h>
// 配置任务周期(单位:ms)
#define TASK1_PERIOD 100 // 任务1每100ms执行一次
#define TASK2_PERIOD 200 // 任务2每200ms执行一次
// 全局变量
uint8_t system_timer_flag = 0;
uint16_t task1_hander = 0, task2_hander = 0;
// 硬件初始化
void HardWareInit(void) {
// 初始化定时器(1ms中断一次)、GPIO等
}
// 任务函数
void run_task_1(void) { /* 任务1具体逻辑 */ }
void run_task_2(void) { /* 任务2具体逻辑 */ }
// 中断服务程序(处理紧急事件)
void ISR1(void) {
// 仅处理中断核心逻辑,耗时操作移交主循环
}
// 检查系统时标是否到达
uint8_t is_system_tick_arrive(void)
{
uint8_t flag = system_timer_flag;
system_timer_flag = 0;
return flag;
}
// 定时器中断(1ms触发一次)
void Timer_ISR(void)
{
system_timer_flag = 1; // 置位时标标志位
}
int main(void)
{
HardWareInit(); /* 硬件相关初始化 */
while(1)
{
if(is_system_tick_arrive()) // 1ms时标到达
{
if(++task1_hander == TASK1_PERIOD) // 任务1周期到
{
task1_hander = 0;
run_task_1(); /* 执行任务1 */
}
if(++task2_hander == TASK2_PERIOD) // 任务2周期到
{
task2_hander = 0;
run_task_2(); /* 执行任务2 */
}
}
}
}
时间片轮询优化了 CPU 利用率,但仍无法突破裸机的核心局限:
-
无优先级管理:高优先级任务(如紧急通信)会被低优先级长耗时任务阻塞;
-
响应时间不确定:若某任务执行超时(如 1ms 时间片内任务执行了 10ms),后续所有任务周期都会偏移;
-
任务同步复杂:多任务共享资源时,需手动处理数据一致性,极易出错。
二、FreeRTOS系统的引入
在上一节的基础上,若想对时间片轮询系统的固有弊端进行改进,就需要在每次进入时钟中断前,保存CPU的当前状态和当前事务用到的一些数据,然后我们进入时钟中断进行时间片处理,若发现有新的更紧急的事务的时间片到来了,则我们改变中断的返回的地址,并在CPU中恢复这个更紧急的事务的现场,然后返回中断开始执行这个更紧急的事务。
裸机系统的核心问题是 "无法高效管理多任务",而 FreeRTOS 作为轻量级 RTOS,本质是一套 "成熟的多任务管理框架"------ 它封装了任务调度、内存管理、同步通信等底层逻辑,这就是为什么我们需要RTOS了。
作为RTOS大家庭中重要的一员,FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。其主要特性有:
轻量级和实时性 :FreeRTOS 的内核非常小,通常只需要大约 6KB 到 12KB 的内存空间(取决于平台和编译选项),适合资源受限的系统,并且具有实时任务调度能力。
可移植性 :FreeRTOS 支持多种处理器和编译环境,使得开发人员可以在不同的硬件平台上使用它。
丰富的 API :FreeRTOS 提供了一套丰富的 API,开发人员可以用来创建任务、管理内存、同步任务和通信等。
可伸缩性 :FreeRTOS 可以根据需要定制和扩展,以满足不同的系统需求。
开源和社区支持:FreeRTOS 是开源的,有一个活跃的社区提供支持。
在FreeRTOS中,根据程序的功能,把程序主体分割成一个个独立的,无限循环且不能返回的子程序,称之为任务。每个任务都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。加入操作系统后,我们不需要关注每个功能模块之间的冲突,重心放在应用程序的实现即可。其执行框架如下图所示。

三、总结
我们不能简单地断言 FreeRTOS 就一定比裸机系统更优秀。技术选型的核心,永远是匹配项目的具体需求。裸机系统以其极简的架构和零操作系统开销,在某些场景下是无可替代的;而 FreeRTOS 则凭借强大的多任务管理能力,成为复杂项目的不二之选。
3.1. 裸机系统:当简单和极致性能是首选
裸机系统(Bare-metal),即不依赖任何操作系统,程序直接在硬件上运行。它在以下场景中表现卓越:
- 项目规模极小:当你的产品功能非常单一,只需要执行几个线性的、顺序的任务,完全没有多任务并行的需求时,裸机是最高效的选择。例如一个简单的 LED 指示灯控制器或一个独立的按键检测模块。
- 追求极致性能与响应:裸机没有操作系统调度、内存管理等额外开销,每一条指令都直接服务于业务逻辑。这对于需要亚微级响应时间的应用,如高速电机驱动、高频信号采集等,是至关重要的。
- 硬件资源极度受限:在一些超低成本、资源极其有限的 MCU 上(如仅有几 KB RAM 和十几 KB Flash 的单片机),FreeRTOS 的内核本身就可能超出硬件的承载能力,此时裸机开发是唯一可行的道路。
3.2. FreeRTOS:当复杂度和可维护性成为刚需
FreeRTOS 作为一款轻量级实时操作系统,为我们提供了强大的工具集,在以下场景中能极大地提升开发效率和系统稳定性:
- 多任务并行处理:当你的项目需要同时处理多个相互独立的功能模块时,例如一个智能网关需要同时进行 Wi-Fi 通信、传感器数据采集、本地显示和按键响应,FreeRTOS 的任务调度器可以轻松管理这些任务,确保高优先级的任务得到及时响应。
- 动态内存与复杂数据处理:FreeRTOS 提供了完善的动态内存管理 API,这在处理网络数据包、动态生成 UI 元素或其他需要大量可变数据的场景中,能有效避免内存碎片和泄漏问题。
- 任务间的同步与互斥:当多个任务需要访问同一个共享资源(如 UART 外设、SPI 总线或一块共享内存)时,FreeRTOS 提供的互斥量、信号量、消息队列等机制,能优雅地解决数据竞争和同步问题,让代码更健壮、更易于维护。