当前位置: 首页 > ai >正文

使用 FreeRTOS 实现简单多任务调度(初识 RTOS)

🚦使用 FreeRTOS 实现简单多任务调度(初识 RTOS)

在这里插入图片描述

“裸机是手动挡,RTOS是自动挡。程序员也要学会偷懒!”
——《从延时到调度:嵌入式人的进阶之路》


🧠 一、什么是 RTOS?为啥你迟早会用上它?

RTOS,全名 Real-Time Operating System(实时操作系统)
简单理解,它是为 MCU 打工的“调度大脑”,能帮你搞定这些烦人的事:

  • 多个任务如何“分时共享 CPU”
  • 谁先执行谁后执行
  • 哪个任务被中断了怎么回来
  • 延时不靠 HAL_Delay(),而是靠“时间片”
  • ……

你说你裸机写得也挺好?

当你项目越来越复杂,一手管理 3 个传感器 + OLED + 蓝牙 + ADC + 一堆中断后,你会感叹:“RTOS,它不香吗?”


在这里插入图片描述

🏗️ 二、FreeRTOS 是啥?能干嘛?

FreeRTOS 是一个轻量级、开源、适用于嵌入式设备的 RTOS。它小到能塞进几 KB 的 Flash,大到能跑在 Cortex-M33 的 MCU 上。

它能做什么?

能力说明
任务管理你写的任务能自动轮流运行(任务调度)
延时控制再也不用 while(1)HAL_Delay()
队列通信多个任务之间可以“发消息”
互斥量防止多个任务抢一个资源打架
中断支持和 ISR 合作,能即时响应硬件事件

🧪 三、我们来写一个:两个任务轮流打印信息

场景设定

我们用两个任务,一个负责打印 “任务1运行中”,另一个打印 “任务2运行中”,每个任务运行后都延时 1 秒钟。


🛠️ 四、搭建 FreeRTOS 工程(以 STM32 为例)

  1. 打开 STM32CubeMX
  2. 选择芯片或开发板,如 STM32F103C8T6
  3. 开启 SYS > Timebase Source 为 “SysTick”
  4. Middleware 中勾选 FreeRTOS
  5. 配置两个任务 Task1 和 Task2
  6. 生成工程并打开 Keil / STM32CubeIDE

📦 五、FreeRTOS 示例代码

#include "cmsis_os.h"
#include "stdio.h"// 任务句柄
osThreadId_t Task1Handle;
osThreadId_t Task2Handle;// 任务1函数
void Task1(void *argument)
{for(;;){printf("任务1运行中\r\n");osDelay(1000); // 延时1秒}
}// 任务2函数
void Task2(void *argument)
{for(;;){printf("任务2运行中\r\n");osDelay(1000); // 延时1秒}
}int main(void)
{HAL_Init();SystemClock_Config();MX_USART2_UART_Init(); // 你用哪个串口就初始化哪个// 创建任务const osThreadAttr_t task1_attr = {.name = "Task1",.priority = (osPriority_t) osPriorityNormal,.stack_size = 128 * 4};Task1Handle = osThreadNew(Task1, NULL, &task1_attr);const osThreadAttr_t task2_attr = {.name = "Task2",.priority = (osPriority_t) osPriorityNormal,.stack_size = 128 * 4};Task2Handle = osThreadNew(Task2, NULL, &task2_attr);// 启动调度器osKernelInitialize();osKernelStart();while (1){// 永远不会执行到这里}
}

🔍 六、代码解析

  • osThreadNew():创建一个任务,传入函数和属性
  • osDelay(ms):让当前任务“睡一觉”,让别人有机会运行
  • osKernelStart():启动 RTOS 的调度器,之后就进入任务世界啦
  • 多个任务根据优先级和时间片轮流运行,实现并发

🧯 七、常见问题

问题原因解决方式
程序卡在 while(1) 不执行任务没调用 osKernelStart()加上它!
任务运行顺序不一致优先级或调度抢占机制影响调整 priority 或加调试日志
串口不打印没初始化串口或 printf 重定向没做好检查 HAL_UART_Init 与重定向

🎨 八、初学者的小贴士

  • 每个任务用死循环 for(;;) 是套路
  • 延时用 osDelay() 替代 HAL_Delay()
  • 任务不能太占 CPU,可以 osDelay(1) 礼貌让位
  • 不要滥用全局变量,多用队列或信号量通信

📚 九、FreeRTOS 术语小科普(别被吓住)

术语中文初学者理解
Task任务一个功能单位
Tick时钟节拍RTOS内部的时间粒度
Scheduler调度器决定谁先运行
Priority优先级谁更重要谁先上
Delay延时任务主动让出 CPU
Mutex/Semaphore互斥量/信号量防止资源抢占、任务同步

✅ 十、总结一句话

FreeRTOS 就像是给你的 MCU 安了个“多线程操作系统”,让它不再只是一个死循环。

只需几行代码,你就可以轻松实现多个功能并发运行,代码结构更清晰,扩展性更强!


📥 点个赞收藏这篇“RTOS第一课”,学会 FreeRTOS,打开嵌入式开发新大门!

💬 评论区欢迎分享你用 RTOS 踩过的坑,或你想实现的小项目,我来教你用 RTOS 玩起来!


http://www.xdnf.cn/news/14964.html

相关文章:

  • HarmonyOS学习记录4
  • 基于SpringBoot+Vue的疫情问卷调查与返校信息管理系统】前后端分离
  • Paimon 原子提交实现
  • 19-C#静态方法与静态类
  • 桌面开发,在线%图书管理系统%开发,基于C#,winform,界面美化,mysql数据库
  • Foundry智能合约测试设计流程
  • Git系列--3.分支管理
  • 学习open62541 --- [79] 在docker中运行open62541工程
  • Java零基础笔记08(Java编程核心:面向对象编程高级 {继承、多态})
  • 编写产品需求文档:黄历日历小程序
  • Python-FAQ-单例模式
  • 论文解析篇 | YOLOv12:以注意力机制为核心的实时目标检测算法
  • 从零用java实现 小红书 springboot vue uniapp(13)模仿抖音视频切换
  • 飞算AI-idea强大的AI工具
  • 函数-3-日期函数
  • Android ViewModel机制与底层原理详解
  • 深度学习 必然用到的 微积分知识
  • 整合Spring、Spring MVC与MyBatis:构建高效Java Web应用
  • 【实习篇】之Http头部字段之Disposition介绍
  • vue快速上手
  • 解决IDEA缺少Add Framework Support选项的可行性方案
  • 跨平台ROS2视觉数据流:服务器运行IsaacSim+Foxglove本地可视化全攻略
  • 单片机STM32F103:DMA的原理以及应用
  • Python通关秘籍之基础教程(一)
  • 供应链管理-采购:谈判方式、理念、技巧
  • 【C++】第四章—— 函数重载 Function Overloading 笔记
  • android activity生命周期温习
  • JSP数据交互
  • JAVA如何实现Redis同步
  • 软件发布的完整流程梳理