1.任务挂起表与就绪表十分相似,只不过就绪表记录的是处于就绪态的任务,任务挂起表记录的是等待某个内核对象的任务,比如任务等待信号量、互斥型信号量、事件标志组或消息队列等。
2.在任务挂起表中,任务是按照优先级排序的,即高优先级的任务放在该表的前面,低优先级的任务放在表的后面。
3.任务挂起表是一个类型为OS_PEND_LIST的数据结构,它的定义位于os.h中。
typedef struct os_pend_list OS_PEND_LIST; // 648行
struct os_pend_list { // 716行 - 720行
OS_PEND_DATA *HeadPtr; // 指向挂起表中的第一个任务
OS_PEND_DATA *TailPtr; // 指向挂起标中的最后一个任务
OS_OBJ_QTY NbrEntries; // 挂起表中的表项数目
};
4.在每种内核对象的头部都包含三个相同的数据域(Type、NamePtr、PendList),这三个数据域合起来叫做OS_PEND_OBJ。OS_PEND_OBJ的定义位于os.h中。
注意:所有任务挂起表的第一个数据域都是内核对象的类型。
typedef struct os_pend_obj OS_PEND_OBJ; // 649行
struct os_pend_obj { // 724行 - 733行
OS_OBJ_TYPE Type; // 类型
CPU_CHAR *NamePtr; // 名称
OS_PEND_LIST PendList; // 挂起表
#if OS_CFG_DBG_EN > 0u // 调试相关
void *DbgPrevPtr;
void *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
};
5.任务挂起表并不是直接指向任务的控制块OS_TCB,而是指向一个OS_PEND_DATA类型的数据结构,它的定义位于os.h中。
OS_PEND_DATA类型的数据结构会在任务被放入任务挂起表时动态的分配到该任务的堆栈空间中。
注:任务的堆栈必须有足够的空间来存储该数据结构。
typedef struct os_pend_data OS_PEND_DATA; // 647行
struct os_pend_data { // 703行 - 712行
OS_PEND_DATA *PrevPtr; // 指向前一个OS_PEND_DATA
OS_PEND_DATA *NextPtr; // 指向后一个OS_PEND_DATA
OS_TCB *TCBPtr; // 指向等待该内核对象的任务的控制块OS_TCB
OS_PEND_OBJ *PendObjPtr; // 指向任务正在等待的内核对象
OS_PEND_OBJ *RdyObjPtr; // 指向已经准备就绪的内核对象(任务等待多个内核对象时)
void *RdyMsgPtr; // 指向OSQPost函数发布的信息(任务等待多个内核对象)
OS_MSG_SIZE RdyMsgSize;
CPU_TS RdyTS; // 内核对象被释放的时间戳
};