FreeRTOS Task Management(2)- 任务控制块(TCB)

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

转载请说明出处,尊重原创,尊重劳动,谢谢!

posted on 2021-06-11 08:18  Yanpeng0527  阅读(1555)  评论(0编辑  收藏  举报