1,源码中的位置
list.h,list.c
2,列表和列表项结构
列表项分为2种:
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)的指针。因此,在包含列表项的对象和列表项本身之间存在双向链接。 */
void * configLIST_VOLATILE pvContainer; /*< 指向放置此列表项的列表的指针(如果有) */
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;
typedef struct xLIST
{
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< 第一个完整性校验值 */
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
ListItem_t * configLIST_VOLATILE pxIndex; /*< 用于查询这个列表. 指向listGET_OWNER_OF_NEXT_ENTRY()调用返回的最后一项。 */
MiniListItem_t xListEnd; /*< 包含最大可能项值的列表项,这意味着它总是在列表的末尾,因此用作标记。 */
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*<第二个完整性校验值 */
} List_t;
3,基本API接口
//设置列表项的所有者。列表项的所有者是包含列表项的对象(通常是TCB)。
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )
//获取列表项的所有者。列表项的所有者是包含列表项的对象(通常是TCB)。
#define listGET_LIST_ITEM_OWNER( pxListItem )
//设置列表项的值。在大多数情况下,该值用于按降序对列表进行排序
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )
//检索列表项的值。该值可以表示任何东西——例如任务的优先级,或者应该解除任务阻塞的时间
#define listGET_LIST_ITEM_VALUE( pxListItem )
//检索给定列表头部列表项的值。
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )
//返回列表顶部的列表项。
#define listGET_HEAD_ENTRY( pxList )
//返回列表顶部的列表项。
#define listGET_NEXT( pxListItem )
//返回标记列表末尾的列表项
#define listGET_END_MARKER( pxList )
//确定列表是否包含任何项。只有当列表为空时,宏的值才为true
#define listLIST_IS_EMPTY( pxList )
//返回列表中项目的数量。
#define listCURRENT_LIST_LENGTH( pxList )
//获取列表中下一个条目的所有者
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
//获取列表中第一个条目的所有者。列表通常按项目值升序排序。
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )
//检查列表项是否在列表中。列表项维护一个指向它所在列表的“容器”指针。这个宏所做的就是检查容器和列表是否匹配。
#define listIS_CONTAINED_WITHIN( pxList, pxListItem )
//返回列表项所属容器的指针。
#define listLIST_ITEM_CONTAINER( pxListItem )
//列表是否已经初始化
#define listLIST_IS_INITIALISED( pxList )
//必须在使用列表之前调用!这会初始化列表结构的所有成员,并将xListEnd项目插入到列表中,作为列表后面的标记。
PRIVILEGED_FUNCTION void vListInitialise( List_t * const pxList );
//必须在使用列表项之前调用。这将列表容器设置为null,这样项目就不会认为它已经包含在列表中。
PRIVILEGED_FUNCTION void vListInitialiseItem( ListItem_t * const pxItem );
//将列表项插入列表。项目将被插入到列表中,其位置由项目值决定(按项目值降序排列)。
PRIVILEGED_FUNCTION void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem );
//将列表项插入列表。该项目将被插入到一个位置,以便它将是listGET_OWNER_OF_NEXT_ENTRY多次调用返回的列表中的最后一个项目。
PRIVILEGED_FUNCTION void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
//从列表中删除项目。列表项有一个指向它所在列表的指针,因此只需要将列表项传递给函数。
PRIVILEGED_FUNCTION UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
4,vListInitialise()结果
5,vListInitialiseItem()结果
6,vListInsert()结果
7,vListInsertEnd()结果
和当前的列表的成员pxIndex有关,插入pxIndex指向列表项的前面。
8,应用实例1-任务
PRIVILEGED_DATA静态List_t pxReadyTasksLists [ configMAX_PRIORITIES ]; / * <就绪任务链表。* /
PRIVILEGED_DATA static List_t xDelayedTaskList1 ; / * <延时任务链表1. * /
PRIVILEGED_DATA静态List_t xDelayedTaskList2 ; / * <延时任务链表2 * /
PRIVILEGED_DATA static List_t xPendingReadyList ; / * <挂起任务链表* /
9.应用实例2-队列
typedef struct QueueDefinition
{
...
List_t xTasksWaitingToSend ; / * <阻塞的任务列表,这些任务等待发送到此队列。按优先顺序存储。* /
List_t xTasksWaitingToReceive ; / * <阻塞等待从该队列读取的任务列表。按优先顺序存储。* /
...
} xQUEUE;
10.应用实例3-软件定时器
PRIVILEGED_DATA static List_t xActiveTimerList1 ;
PRIVILEGED_DATA static List_t xActiveTimerList2 ;
11,上述3种列表是如何工作的呢,有哪些可操作的API?