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 标准配置,不要关闭,否则系统实时性崩溃

相关推荐
2501_918126912 小时前
学习所有用c语言定义stm32的语句
c语言·stm32·嵌入式硬件·学习·个人开发
handler012 小时前
算法:Trie树(字典树)
c语言·数据结构·c++·笔记·算法·深度优先
Book思议-3 小时前
【数据结构考研真题】链表题
c语言·数据结构·算法·链表·408·计算机考研
for_ever_love__3 小时前
Objecgtive-C学习实例对象,类对象, 元类对象与 isa指针
c语言·学习·ios
zly88653723 小时前
windsurf rules与skill的使用
linux·c语言·开发语言·驱动开发
Lzh编程小栈4 小时前
数据结构与算法——单链表超详解(C语言完整实现 + 面试高频题)
c语言·开发语言·面试
聆风吟º4 小时前
【C标准库】C语言memset函数详解:从原理到实战避坑
c语言·开发语言·库函数·memset
Book思议-4 小时前
【数据结构实战】双向链表:删除节点
c语言·数据结构·算法·链表
爱编码的小八嘎13 小时前
C语言完美演绎4-7
c语言