FreeRTOS Task Management(2)- 任務控制塊(TCB)
/* FreeRTOS Kernel V10.4.1 */
本文原文鏈接:https://www.cnblogs.com/yanpio/p/14873627.html
1 任務控制塊(Task Control Block, TCB)
TCB
是每個任務所有操作的基礎,因此有必要先了解一下TCB
的詳細構成。部分變量會在之后用到時,再補充說明。
/*
* Task control block. A task control block (TCB) is allocated for each task,
* and stores task state information, including a pointer to the task's context
* (the task's run time environment, including register values)
*/
typedef struct tskTaskControlBlock
{
/* 棧頂<元素>指針,注意與 pxEndOfStack 的區別。 必須是結構體的第一個成員. */
volatile StackType_t * pxTopOfStack;
/* MPU 模塊設置,必須是結構體的第二個成員 */
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings;
#endif
ListItem_t xStateListItem; /* 列表項指示任務當前的狀態 (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /* 用於在事件列表中. */
UBaseType_t uxPriority; /* 任務優先級(0為優先級最低). */
StackType_t * pxStack; /* 棧底指針,指向棧開始處. */
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任務名 */
/* 如果棧向上生長,則定義棧頂指針 */
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t * pxEndOfStack;
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; /* 保存臨界區的棧深度. 在函數vTaskEnterCritical() 和 vTaskExitCritical()中會維護這個值*/
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber; /*TCB的編號,每次增加一個task,TCB的編號就會增加. */
UBaseType_t uxTaskNumber; /*task的編號,其值和uxTCBNumber相等,可用於調試追蹤. */
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*上一次分配給該任務的優先級,用於優先級繼承機制. */
UBaseType_t uxMutexesHeld; /* 持有的信號量 */
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
/* 存儲一些私有的變量 */
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
/* task 運行的總時間 */
#if ( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter;
#endif
/* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html for additional information. */
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xNewLib_reent;
#endif
/* 任務通知相關變量 */
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
#endif
/* FreeRTOS.h 中有關於 tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE 的詳細注釋。主要的作用是決定task創建的資源是動態還是靜態分配內存. */
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
uint8_t ucStaticallyAllocated; /* 標記stack 和 TCB分配方式,在刪除任務時,根據此標志來對應釋放內存 */
#endif
/* delay 終止標志 */
#if ( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
/* error number*/
#if ( configUSE_POSIX_ERRNO == 1 )
int iTaskErrno;
#endif
} tskTCB;
2 相關全局變量
/* 當前TCB,task運行時,實質上就是對TCB進行操作 */
TCB_t * volatile pxCurrentTCB = NULL;
/* 不同的優先級有不同的ready list。處於ready狀態的task會依據優先級,被添加到此list中 */
static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];
/* task delay操作時, tick計數器不斷累積,可能會發生溢出(循環計數,比如從0計數到100,滿100后又重新從0開始計數)
* 因此,需要兩個list來記錄,xDelayedTaskList2用於計數溢出的task */
static List_t xDelayedTaskList1;
static List_t xDelayedTaskList2;
/* 分別指向上述兩個不同的list */
static List_t * volatile pxDelayedTaskList;
static List_t * volatile pxOverflowDelayedTaskList;
/* 檔調度器掛起時,處於ready狀態的task被添加到該list中。等調度器恢復時,這些task會從該list中移出 */
static List_t xPendingReadyList;
/* task被刪除后,其資源不會立刻進行釋放。而是由idle task去處理這些資源釋放的活。
* 而idle task 不一定立刻就能被調度器執行,因此需要將被刪除任務的相關信息記錄下來 */
#if ( INCLUDE_vTaskDelete == 1 )
/*任務被刪除后,添加到此list中 */
static List_t xTasksWaitingTermination;
/* 等待清理內存的任務數量 */
static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U;
#endif
/* 處於Suspend狀態的task,會被添加到此list中 . */
#if ( INCLUDE_vTaskSuspend == 1 )
static List_t xSuspendedTaskList;
#endif
轉載請說明出處,尊重原創,尊重勞動,謝謝!