什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
struct List
{
type data;
struct list *next;
};
使用Source Insight 打开freeRtos源码,在list.h文件中定义freeRtos中的基本数结构。如下图所示
其中struct xMINI_LIST_ITEM是最小的链表元素,是一个双向链表的结构。struct xLIST_ITEM 和typedef struct xLIST是后面用于任务调度和处理的基本数据结构。至于其中每项的意思在后面会做解释。
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
上面的宏是设置struct xLIST_ITEM中pxOwner属性的值。
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
上面的宏是获取struct xLIST_ITEM中pxOwner属性的值。
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
上面的宏是获取和设置struct xLIST_ITEM中xItemValue属性的值。
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
上面宏是获取头节点后的struct xLIST_ITEM中xItemValue属性的值。
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
上面宏是获取当前struct xLIST 节点struct xLIST_ITEM节点属性的下一个节点。
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
上面宏是获取当前struct xLIST_ITEM节点的下一个节点。
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
上面宏是获取当前struct xLIST 节点struct xLIST_ITEM节点xItemValue属性的值。
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
上面宏是获取xListEnd的指针值
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
上面宏是判断链表是否为空。
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
上面宏是判断链表的长度。
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
{ \
List_t * const pxConstList = ( pxList ); \
/* Increment the index to the next item and return the item, ensuring */ \
/* we don't return the marker used at the end of the list. */ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{ \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
}
遍历链表找到最后一个节点pvOwner属性。
还有很多宏这里不列举了,freeRtos链表主要实现了初始化,在合适位置插入和删除指定节点这几个主要函数。
该初始化函数,初始了一个双向循环链表,所有指针域都指向了自己。
步骤图如下
这个函数的功能就是确保每个任务都获得相同的CPU时间片。
在freeRtos中list.c和list.h定义了freeRtos的基本数据结构链表,这是一个双向循环链表,实现了一些基本操作函数,方便后续任务的创建以及调度管理。