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

使用 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.dtcms.com/a/271885.html

相关文章:

  • Excalidraw:一款轻量、高效、极具手感的在线白板工具
  • 【免费数据】2020年中国高精度耕地范围矢量数据
  • 解析几何几百年重大错误:将无穷多各异圆盘(球)误为同一点集
  • 语音转文字「本地化」新解!Whisper Web+cpolar实现零服务器部署与远程操作
  • 大数据在UI前端的应用创新:基于用户画像的精准广告投放系统
  • imx6ull-裸机学习实验17——SPI 实验
  • 《数据库》第一次作业:MySQL数据库账户及授权
  • FeatherScan v4.0 – 适用于Linux的全自动内网信息收集工具
  • 2025.07.09华为机考真题解析-第二题200分
  • 华为L1-L6流程体系核心框架
  • 2025.07.09华为机考真题解析-第三题300分
  • java与sql的日期类型常用教程讲解
  • 常见射频电路板工艺流程
  • 《信号与系统》学习笔记——第八章
  • 大小端模式如何影响位域中各成员的位序;位域的其他细节问题
  • k8s:安装 Helm 私有仓库ChartMuseum、helm-push插件并上传、安装Zookeeper
  • 正点原子 文件权限
  • Spring核心原理的快速入门:快速了解IoC与DI
  • RHCE考试 ——笔记
  • 【Linux手册】从接口到管理:Linux文件系统的核心操作指南
  • Redis数据安全性分析
  • PyTorch Tensor 操作入门:转换、运算、维度变换
  • 【NLP入门系列六】Word2Vec模型简介,与以《人民的名义》小说原文实践
  • IPv4和IPv6双栈配置
  • 【K8S】Kubernetes 使用 Ingress-Nginx 基于 Cookie 实现会话保持的负载均衡
  • HCIA第一次实验报告:静态路由综合实验
  • day11-微服务面试篇
  • C++11 std::is_sorted 和 std::is_sorted_until 原理解析
  • CentOs 7 MySql8.0.23之前的版本主从复制
  • 无缝矩阵与普通矩阵的对比分析