STM32学习日志_FreeRTOS_day2_任务状态

参考:

大D老师

03-RTOS任务状态转换_哔哩哔哩_bilibili

任务_Task

本质

 任务是程序执行的最小单元,相当于独立的"微型程序"。

特性

  • 独立的执行流(程序计数器)
  • 专属的栈空间(存储局部变量、返回地址等)
  • 优先级属性(0~configMAX_PRIORITIES-1)
  • 任务控制块(TCB)存储状态信息
// 任务创建示例
xTaskCreate(
    vTaskFunction,     // 任务函数
    "Task_Name",       // 任务名称
    configMINIMAL_STACK_SIZE, // 栈大小
    NULL,              // 任务参数
    tskIDLE_PRIORITY + 2, // 优先级
    &xTaskHandle       // 任务句柄
);

任务状态及其转换

创建态(Created)

  • 特征:任务已被创建但未加入调度

  • 进入条件xTaskCreate()调用成功

  • 转换

    • 创建态 → 就绪态:调度器启动后(vTaskStartScheduler()

 

 就绪态(Ready)

  • 特征:准备执行,等待CPU资源

  • 队列:位于就绪列表(Ready List)中

  • 转换

    •  → 运行态:被调度器选中

    • → 阻塞态:主动等待资源

    • → 挂起态:被显式挂起

    • → 删除态:被删除

 就绪态 → 运行态:

 运行态(Running)

  • 特征:正在使用CPU执行

  • 单核限制:仅1个任务处于此状态

  • 转换

    • → 就绪态:时间片耗尽或更高优先级任务就绪

    • → 阻塞态:调用阻塞API

    • → 挂起态:调用vTaskSuspend()

    • → 删除态:调用vTaskDelete()

运行态 → 阻塞态:

 运行态 → 挂起态:

阻塞态(Blocked) 

  • 特征:等待外部事件,不消耗CPU

  • 等待事件类型

    • 定时器事件:vTaskDelay()

    • 同步事件:xSemaphoreTake()

    • 通信事件:xQueueReceive()

    • 通知事件:ulTaskNotifyTake()

  • 转换

    • → 就绪态:等待事件发生

    • → 删除态:被删除

阻塞态 → 就绪态:

 

 挂起态(Suspended)

  • 特征:被强制暂停,不参与调度

  • 控制API:

    vTaskSuspend(xTaskHandle);   // 挂起任务
    vTaskResume(xTaskHandle);    // 恢复任务
    xTaskResumeFromISR();        // 中断中恢复

  • 转换

    • → 就绪态:被显式恢复

 挂起态 → 就绪态:

删除态(Deleted)

  • 特征:任务已终止,资源待回收

  • 内存回收:由空闲任务(Idle Task)清理

  • APIvTaskDelete(xTaskHandle)

状态转换触发条件 

转换方向API/事件典型场景
Ready → Running调度器选择更高优先级任务阻塞
Running → BlockedvTaskDelay()定时等待
xQueueReceive()等待队列数据
xSemaphoreTake()获取信号量
Blocked → Ready定时器超时vTaskDelay()结束
xQueueSend()队列数据到达
xSemaphoreGive()信号量释放
→ SuspendedvTaskSuspend()调试时暂停任务
Suspended → ReadyvTaskResume()恢复调试任务
→ DeletedvTaskDelete()结束不再需要的任务

 优先级与状态转换

优先级影响

  • 高优先级任务会立即抢占低优先级任务
  • 同优先级任务采用时间片轮转(需启用configUSE_TIME_SLICING

优先级反转问题

  • 场景:低优先级任务持有高优先级任务需要的资源
  • 解决方案:优先级继承(configUSE_MUTEXES_INHERIT)

 状态监控与调试

API获取状态

eTaskState eTaskGetState(TaskHandle_t xTask);
/* 返回状态枚举:
eRunning, eReady, eBlocked, 
eSuspended, eDeleted, eInvalid */

 栈溢出检测

// 获取栈高水位线
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask);

 运行时可视化

// 打印所有任务状态
vTaskList(pcWriteBuffer); 
/* 输出格式:
TaskName  State  Pri  Stack  Num */

实践 

栈空间分配

  • 最小栈 ≥ 128字(512字节)
  • 复杂任务需≥256字(1KB)
  • 使用uxTaskGetStackHighWaterMark()验证

 状态转换原则

void vTaskExample(void *pvParameters) {
  for(;;) {
    // 1. 运行态处理逻辑
    ProcessData();
    
    // 2. 主动进入阻塞态(让出CPU)
    vTaskDelay(pdMS_TO_TICKS(100));
    
    // 3. 等待同步事件
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
  }
}

避免常见错误

  • 禁止在中断中调用阻塞API

  • 删除任务前释放其占用的资源

  • 挂起任务时考虑其对系统的影响

eg:

// 任务A:高优先级
void vTaskA(void *pv) {
  while(1) {
    // 获取信号量(可能阻塞)
    xSemaphoreTake(xSem, portMAX_DELAY); 
    ProcessCritical();
    xSemaphoreGive(xSem);
  }
}

// 任务B:低优先级 
void vTaskB(void *pv) {
  vTaskDelay(100); // 进入阻塞态
  // 此时任务A若等待信号量,任务B可运行
  xSemaphoreTake(xSem, 0); // 尝试获取
  // ...
}

案例

STM32cubeIDE,STM32F103C8T6

任务:

用CubeMX创建:

  • OLED显示任务(LED1,LED2)状态;
  • LED1任务:控制LED1以500ms周期翻转亮灭;
  • LED2任务:控制LED2以1000ms周期翻转亮灭;
  • 按键KEY1任务:按下,挂起or删除LED1任务;
  • 按键KEY2任务:按下,创建or删除LED2任务;

解析

iic通信控制OLED屏幕

实践

AI给出代码,工程师负责修改,调试等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值