1.列表与列表项
在前面的介绍中提到过,任务的管理涉及到了列表与列表项,针对不同的任务状态建立不同的列表,实现任务的追踪与管理。
//就绪列表和阻塞列表
PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];//就绪列表
PRIVILEGED_DATA static List_t xDelayedTaskList1; //延迟列表1
PRIVILEGED_DATA static List_t xDelayedTaskList2; //延迟列表2
//当任务从挂起或阻塞状态被激活时,如果调度器也处于挂起状态,任务会先放进xPendingReadyList队列,等到调度器恢复时(xTaskResumeAll)再将这些xPendingReadyList里的任务一起放进就绪列表
PRIVILEGED_DATA static List_t xPendingReadyList; //暂存列表
#if( INCLUDE_vTaskDelete == 1 )
PRIVILEGED_DATA static List_t xTasksWaitingTermination; //僵尸列表
#endif
#if ( INCLUDE_vTaskSuspend == 1 )
PRIVILEGED_DATA static List_t xSuspendedTaskList; //挂起列表
#endif
1.1 列表
列表的结构类似于一个双向链表,列表项可以插入到列表中。列表的结构体List_t
包括以下内容:
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE //列表完整性检查
volatile UBaseType_t uxNumberOfItems; //列表中包含的列表项数目
ListItem_t * configLIST_VOLATILE pxIndex; //用来记录当前列表项索引号
MiniListItem_t xListEnd; //末尾列表项,用来表示列表结束
listSECOND_LIST_INTEGRITY_CHECK_VALUE //列表完整性检查
} List_t;
列表的初始化就是初始化结构体的各个成员变量,初始化后的列表结构如下:
- 列表中包含一个迷你列表项,用来表示列表结束
- 列表项的排序是按列表值从小到大排序的,末尾列表项的列表项值初始化为
portMAX_DELAY
,即0xFFFFFFFF
- 列表中只有一个末尾列表项,但不计算在列表项数量内
1.2 列表项
列表项就是存放在列表中的项目,FreeRTOS
提供了两种列表项:列表项和迷你列表项。列表项定义如下:
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; //记录此列表项归谁所有,通常是任务控制块
struct xLIST * configLIST_VOLATILE pxContainer; //记录列表项归哪个列表,指向列表
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE //列表项完整性检查
typedef struct xLIST_ITEM ListItem_t;
迷你列表项定义如下:
struct xMINI_LIST_ITEM
{
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
configLIST_VOLATILE TickType_t xItemValue;
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;
这里找了一个图来表示列表与列表项的关系,图中的每个人代表一个列表项,两个胳膊分别对应pxNext
和pxPrevious
。
2.列表项操作
2.1 列表项插入
列表项插入有两种方法:列表项插入和列表项末尾插入。列表项插入方式是按照 xItemValue
值按照升序方式排列。
void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
列表项插入过程如下:
2.2 列表项删除与遍历
(1)列表项删除
列表项删除,就是将指定的列表项从列表中删除掉,然后将删除列表项前后两个列表项连接起来。
(2)列表项遍历
列表项遍历主要用于从多个同优先级的就绪任务中查找下一个要运行的任务。