任务控制块
在进行创建任务时,每一个任务会分配一片空间,用来保存任务各种状态、堆栈空间地址、任务优先级、任务名字等。这个任务控制块(TCB_t)最基本的项有,
volatile StackType_t *pxTopOfStack; //任务栈顶指针,这个栈是指一个任务所对应的寄存器组最后一项的指针。
ListItem_t xStateListItem; //任务状态列表项来表示任务所处的状态
ListItem_t xEventListItem;//任务控制块内置的事件链表节点,通过这个节点可以将任务和事件链表建立链接。
这里详细说一下Listltem_t这个结构体的定义
/**********************************Listltem_t******************************/
struct xLIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
configLIST_VOLATILE TickType_t xItemValue; //用于任务排序
struct xLIST_ITEM * configLIST_VOLATILE pxNext; //链表指针,指向下一个队列
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; //链表指针,指向上一个队列
void * pvOwner; //任务TCB的指针 ,该任务属于某个TCB,使OS能够通过列表项找到他所属的任务,在任务切换时起这非常重要的作用
void * configLIST_VOLATILE pvContainer; //用于记录此列表项归哪个列表 ,用于记录任务当前所处的状态
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;
/***************************************************************************/
UBaseType_t uxPriority; //任务优先级,指定任务的优先级,0的优先级最低。数据类型UBaseType_t 是uint32_t的别名。
StackType_t *pxStack;//pxStack:StackType_t指针变量,指向【任务栈】的起始地址;
char pcTaskName[ configMAX_TASK_NAME_LEN ];//函数变量名,绑定后抽象为任务
保留上下文
在FreeRTOS中,任务切换时需要保存和恢复任务的上下文,以便当任务再次被调度时能够从中断点继续执行。任务的上下文通常包括CPU寄存器的状态、堆栈指针以及其他与任务相关的信息。FreeRTOS通过**任务控制块(Task Control Block, TCB)和任务堆栈来存储这些上下文信息。具体来说,保存的上下文包括:
1. 核心寄存器
Cortex-M3处理器的上下文包括以下寄存器,这些寄存器在任务切换时被保留:
R0-R12:通用寄存器。
R13 (SP):堆栈指针,分为MSP(主堆栈指针)和PSP(进程堆栈指针)。在FreeRTOS中,任务通常使用PSP。
R14 (LR):链接寄存器,保存任务函数返回地址。
R15 (PC):程序计数器,指向当前执行的指令地址。
xPSR:程序状态寄存器,保存任务的状态标志,如中断使能标志。
2. 保存位置
上下文信息被分为两个地方存储:
任务堆栈:任务的寄存器状态(R0-R12、PC、LR、xPSR)都保存在任务的堆栈中。每个任务都有自己的堆栈,在任务切换时,FreeRTOS会将当前任务的上下文推送到堆栈中。当任务被重新调度时,这些寄存器值会从堆栈中弹出,恢复到CPU寄存器中。
任务控制块(TCB):FreeRTOS为每个任务分配一个任务控制块,存储任务的元数据和控制信息。TCB中包含指向任务堆栈顶(SP)的指针。当任务切换发生时,FreeRTOS会将当前任务的堆栈指针保存到该任务的TCB中,并从下一个任务的TCB中恢复堆栈指针,而任务对应的TCB会被分配到堆区。
3. 任务切换过程
当FreeRTOS进行任务切换时,保存和恢复上下文的过程如下:
保存当前任务上下文:当前任务的寄存器状态被保存到它的堆栈中,堆栈指针(PSP)被保存到TCB中。
切换任务:FreeRTOS的调度器选择下一个要运行的任务,并从它的TCB中读取保存的堆栈指针。
恢复新任务上下文:从任务堆栈中恢复该任务的寄存器状态到CPU中,程序计数器(PC)被设置为任务执行中断时的指令地址,任务继续运行。
4. 硬件支持的上下文保存
Cortex-M3架构支持硬件自动保存上下文,当中断或异常发生时,硬件会自动将部分寄存器(R0-R3、R12、LR、PC和xPSR)推送到当前使用的堆栈中。FreeRTOS通过软件完成剩余寄存器的保存与恢复。
总结:
在FreeRTOS中,任务切换时上下文的保存包括核心寄存器的状态,这些内容保存在每个任务的堆栈中,而堆栈指针(SP)则存储在任务控制块(TCB)中。当切换到其他任务时,FreeRTOS会根据TCB中的信息恢复任务的上下文。