FreeRTOS连载05:任务状态机 - Ready、Running、Blocked、Suspended状态转换深度解析

引言

任务状态机是FreeRTOS调度器的核心,它定义了任务在不同时刻的状态以及状态之间的转换规则。理解任务状态机对于掌握FreeRTOS的调度机制至关重要。本文将深入分析FreeRTOS V11.1.0中任务状态的定义、转换机制和实现细节。

1. 任务状态定义

FreeRTOS定义了以下几种任务状态:

/* 任务状态枚举 */
typedef enum
{
    eRunning = 0,    /* 运行状态:任务正在执行 */
    eReady,          /* 就绪状态:任务准备运行,等待调度器分配CPU */
    eBlocked,        /* 阻塞状态:任务等待某个事件或资源 */
    eSuspended,      /* 挂起状态:任务被显式挂起,不参与调度 */
    eDeleted,        /* 删除状态:任务已被删除,TCB等待清理 */
    eInvalid         /* 无效状态:用于错误检查 */
} eTaskState;

2. 任务状态机架构

2.1 状态转换图

    创建
     ↓
  ┌─────────┐    调度器选中    ┌─────────┐
  │  Ready  │ ──────────────→ │ Running │
  │ (就绪)   │ ←────────────── │ (运行)   │
  └─────────┘   时间片到期     └─────────┘
       ↑           或被抢占          │
       │                          │
   事件发生                    等待事件
   资源可用                    或资源
       │                          │
       │                          ↓
  ┌─────────┐                ┌─────────┐
  │ Blocked │                │Suspended│
  │ (阻塞)   │                │ (挂起)   │
  └─────────┘                └─────────┘
       │                          │
       └──────── 删除任务 ──────────┘
                    ↓
               ┌─────────┐
               │ Deleted │
               │ (删除)   │
               └─────────┘

2.2 状态链表组织

FreeRTOS使用不同的链表来管理处于不同状态的任务:

/* 就绪任务链表数组 - 每个优先级一个链表 */
PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
​
/* 延时任务链表 */
PRIVILEGED_DATA static List_t xDelayedTaskList1;
PRIVILEGED_DATA static List_t xDelayedTaskList2;
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;
PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;
​
/* 挂起任务链表 */
#if ( INCLUDE_vTaskSuspend == 1 )
    PRIVILEGED_DATA static List_t xSuspendedTaskList;
#endif
​
/* 等待删除的任务链表 */
#if ( INCLUDE_vTaskDelete == 1 )
    PRIVILEGED_DATA static List_t xTasksWaitingTermination;
#endif
```## 3. 状
态转换机制详解
​
### 3.1 Ready → Running 转换
​
当调度器选择一个就绪任务运行时发生此转换:
​
```c
/* 任务选择宏 - 单核版本 */
#define taskSELECT_HIGHEST_PRIORITY_TASK()                                       \
    do {                                                                         \
        UBaseType_t uxTopPriority = uxTopReadyPriority;                          \
                                                                                 \
        /* 找到包含就绪任务的最高优先级队列 */                                        \
        while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) != pdFALSE ) \
        {                                                                        \
            configASSERT( uxTopPriority );                                       \
            --uxTopPriority;                                                     \
        }                                                                        \
                                                                                 \
        /* 轮转选择同优先级任务 */                                                  \
        listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
        uxTopReadyPriority = uxTopPriority;                                      \
    } while( 0 )
​
/* 实际的任务切换函数 */
void vTaskSwitchContext( void )
{
    if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
    {
        /* 调度器被挂起,记录需要切换的标志 */
        xYieldPendings[ portGET_CORE_ID() ] = pdTRUE;
    }
    else
    {
        xYieldPendings[ portGET_CORE_ID() ] = pdFALSE;
        
        /* 选择下一个要运行的任务 */
        taskSELECT_HIGHEST_PRIORITY_TASK();
        
        /* 更新任务运行状态 */
        #if ( configNUMBER_OF_CORES > 1 )
        {
            if( pxCurrentTCB != NULL )
            {
                pxCurrentTCB->xTaskRunState = portGET_CORE_ID();
            }
        }
        #endif
    }
}

3.2 Running → Ready 转换

任务从运行状态转为就绪状态的几种情况:

3.2.1 时间片到期
/* 在Ti
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VehSwHwDeveloper

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值