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

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

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


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

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

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

你说你裸机写得也挺好?

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


使用 FreeRTOS 实现简单多任务调度(初识 RTOS)_第1张图片

️ 二、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 玩起来!


你可能感兴趣的:(FreeRTOS,嵌入式开发,多任务调度,RTOS单片机)