基于freertos的嵌入式系统开发(八)FreeRTOS的TCB
简介
FreeRTOS为了实现任务调度。首先就需要定义任务调度的数据结构,来保存任务堆栈结构、任务状态、任务ID、任务的优先级等信息。这些信息集中存放在Task control block,即TCB,每个Task被分配唯一的TCB,TCB重要信息有:
1.栈顶指针pxTopOfStack,必须是TCB的第一个成员,指针指向任务栈顶。任务在调度过程中,随着状态的不同,还有压栈或出栈操作,所以,该指针声明为volatile ,禁止编译器优化。
2.状态列表项(xStateListItem),通项记录TCB所在状态。任务调度时候,该列表项在就绪列表,当前运行项,等待列表不停切换。如下图:
3.任务优先级(uxPriority)
其他辅助选项。
TCB的定义
freertos的TCB对应如下:
typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. /
{
volatile StackType_t * pxTopOfStack; /< 栈顶指针,中断或任务切换时,会对任务压栈,恢复运行时,会出栈,栈顶指针就跟着变化Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
#if ( portUSING_MPU_WRAPPERS == 1 ) //MPU相关设置
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
#endif
ListItem_t xStateListItem; /*< 状态列表项,不同的状态会挂接在不同的状态链表下 The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /*< Event列表项,不同的event会挂接到不同事件链表下Used to reference a task from an event list. */
UBaseType_t uxPriority; /*< 优先级,0最底,数字越大优先级越高The priority of the task. 0 is the lowest priority. */
StackType_t * pxStack; /*<堆栈起始地址 Points to the start of the stack. */
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< 任务名称存储区Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
// 根据栈是否向上生长,决定是否定义pxEndOfStack,用于栈溢出判定
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */
#endif
//支持嵌套时,记录临界段的嵌套层数,
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
#endif
//调试跟踪项定义,保存一个tcb编号和一个task编号,每个任务都不同
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
#endif
//支持互斥信号时,记录互斥信号量个数
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
UBaseType_t uxMutexesHeld;
#endif
// task的钩子函数配置,
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
//任务的线程本地存储指针,本task私有的存储空间
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
//记录task总运行时间变量
#if ( configGENERATE_RUN_TIME_STATS == 1 )
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
/* Allocate a Newlib reent structure that is specific to this task.
* Note Newlib support has been included by popular demand, but is not
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
* responsible for resulting newlib operation. User must be familiar with
* newlib and must provide system-wide implementations of the necessary
* stubs. Be warned that (at the time of writing) the current newlib design
* implements a system-wide malloc() that must be provided with locks.
*
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
* for additional information. */
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
/* See the comments in FreeRTOS.h with the definition of
* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE.
根据动态创建任务配置项,定义ucStaticallyAllocated变量标识 */
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
#endif
/* delay 结束标识 */
#if ( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
#if ( configUSE_POSIX_ERRNO == 1 )
int iTaskErrno;
#endif
} tskTCB;