FreeRTOS中创建任务的顺序是否会影响任务运行的顺序?【面试重点】

结论

任务的运行顺序 和 创建顺序 没有任何关系! FreeRTOS 是抢占式调度器,任务执行顺序只由 2 个规则决定:

  1. 优先级高的任务 → 永远先运行(核心规则)
  2. 同优先级任务新创建的任务会立即抢占当前任务 ,直接导致后创建、先运行

原理(FreeRTOS 调度核心机制)

1. 抢占式调度器(最重要)

FreeRTOS 默认开启 抢占式调度

  • 只要有更高优先级 的任务进入就绪态,CPU 会立刻停止当前任务,去运行高优先级任务
  • 优先级:数值越大,优先级越高(CMSIS-V2 / STM32CubeMX 配置)

2. 同优先级任务的规则

创建的任务优先级完全相同 (都是 osPriorityNormal):

  1. 同优先级任务默认使用 时间片轮转调度
  2. 新创建的任务 会被插入到就绪链表的头部
  3. 调度器会立即切换 到这个新任务运行→ 表现为:谁后创建,谁先抢 CPU 运行

3. 补充:调度器启动前创建任务

如果在 vTaskStartScheduler() 之前创建所有任务:

  • 所有任务排队进入就绪链表
  • 调度器启动后,运行最高优先级任务
  • 同优先级:运行链表第一个任务(先创建的先运行)

运行机制

cpp 复制代码
// 都是 osPriorityNormal 同优先级
xTaskCreate(Input_Task, ...);  // 先创建
xTaskCreate(platform_task, ...); // 后创建

执行流程:

  1. CPU 正在运行 game1_task
  2. 调用 xTaskCreate 创建 platform_task
  3. 新任务优先级 = 当前任务优先级
  4. FreeRTOS 直接抢占切换 :暂停 game1_task,先运行 platform_task
  5. 所以你看到:后创建的任务先运行

可复制验证代码(直观看到效果)

cpp 复制代码
// 三个同优先级任务
void Task1(void *p)
{
    while(1)
    {
        LCD_PrintString(0,0,"Task1 Run");
        vTaskDelay(500);
    }
}

void Task2(void *p)
{
    while(1)
    {
        LCD_PrintString(0,2,"Task2 Run"); // 后创建,会先打印!
        vTaskDelay(500);
    }
}

void game1_task(void *params)
{
    // 先创建 Task1
    xTaskCreate(Task1, "Task1", 128, NULL, osPriorityNormal, NULL);
    // 后创建 Task2
    xTaskCreate(Task2, "Task2", 128, NULL, osPriorityNormal, NULL);

    while(1)
    {
        vTaskDelay(100);
    }
}

✅ 现象:LCD 先显示 Task2 Run,验证后创建先运行


避坑提醒(STM32F103 + FreeRTOS 专属)

  1. 绝对不要依赖「任务创建顺序」控制执行流程 同优先级任务的执行顺序是不确定的,换芯片 / 升级库可能失效

  2. 需要优先运行的任务 → 提高优先级例:平台控制任务需要优先运行

    复制代码
    // 高优先级
    xTaskCreate(platform_task, ..., osPriorityAboveNormal, NULL);
    // 普通优先级
    xTaskCreate(Input_Task, ..., osPriorityNormal, NULL);
  3. 业务同步不要靠执行顺序队列、任务通知、互斥锁、信号量 做任务同步(你项目中已用队列,正确)

  4. 抢占式调度默认开启这是 FreeRTOS 标准配置,不要关闭,否则系统实时性崩溃

相关推荐
qq_339554821 天前
英飞凌ModusToolbox环境搭建
c语言·eclipse
张張4081 天前
(域格)环境搭建和编译
c语言·开发语言·python·ai
༾冬瓜大侠༿1 天前
vector
c语言·开发语言·数据结构·c++·算法
独小乐1 天前
009.中断实践之实现按键测试|千篇笔记实现嵌入式全栈/裸机篇
linux·c语言·驱动开发·笔记·嵌入式硬件·arm
Proxy_ZZ01 天前
从零实现LDPC比特翻转译码器:C语言实战与底层逻辑解析
c语言·算法
ambition202421 天前
斐波那契取模问题的深入分析:为什么提前取模是关键的
c语言·数据结构·c++·算法·图论
艾莉丝努力练剑1 天前
C++ 核心编程练习:从基础语法到递归、重载与宏定义
linux·运维·服务器·c语言·c++·学习
Ghost Face...1 天前
Linux USB 全栈解析:OTG + Type-C + PD 内核架构(架构师级)
linux·c语言·架构
蓝牙先生1 天前
22_backlightLinux内核模块
linux·c语言
ambition202421 天前
【算法详解】飞机降落问题:DFS剪枝解决调度问题
c语言·数据结构·c++·算法·深度优先·图搜索算法