FreeRTOS的链表功能源码分析
一、基础介绍
链表是FreeRTOS其他功能实现的基础,提供了清晰的API接口,本次分析其具体实现。
二、结构体成员介绍
// 这里忽略了volatile关键字
// 链表成员
struct xLIST_ITEM{
TickType_t xItemValue; // 值,用作排序用
struct xLIST_ITEM * pxNext; // 指向下个成员指针
struct xLIST_ITEM * pxPrevious; // 指向前个成员指针
void * pvOwner; // 属于哪个TCB
void * pvContainer; // 属于哪个链表
};
// MINI链表成员--用作链表的最后一项
struct xMINI_LIST_ITEM
{
TickType_t xItemValue; // 值,用作排序用
struct xLIST_ITEM * pxNext; // 指向下个成员指针
struct xLIST_ITEM * pxPrevious; // 指向前个成员指针
};
// 链表
typedef struct xLIST
{
UBaseType_t uxNumberOfItems; // 链表成员计数
ListItem_t * pxIndex; // 指向最后一个链表成员的索引
MiniListItem_t xListEnd; // 链表最后一个成员
}List_t;
三、主要API介绍
// 这里忽略了检查和assert等
// 初始化链表节点
void vListInitialiseItem( ListItem_t * const pxItem )
{
pxItem->pvContainer = NULL;
}
// 初始化链表
void vListInitialise( List_t * const pxList )
{
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); // 设置pxIndex属性
pxList->xListEnd.xItemValue = portMAX_DELAY; // 0xffffffff
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); // 指向本身
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); // 指向本身
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; // 计数0
}
// 插入尾部
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t * const pxIndex = pxList->pxIndex; // 链表的最后一个节点
pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem; // pxNewListItem插到pxIndex的前面
pxNewListItem->pvContainer = ( void * ) pxList; // 设置pvContainer
( pxList->uxNumberOfItems )++; // 计数++
}
// 根据链表节点值升序插入
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator; // 遍历链表用
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; // 待插入链表节点的值,排序用
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious; // 如果是portMAX_DELAY,直接定位到链表尾部
}
else
{
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
// 遍历得到pxIterator,pxNewListItem应该插入到pxIterator和pxIterator->pxNext之间
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem; // pxNewListItem插入到pxIterator和pxIterator->pxNext之间
pxNewListItem->pvContainer = ( void * ) pxList; // 设置pvContainer
( pxList->uxNumberOfItems )++; // 计数++
}
// 移除链表节点
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; // 得到链表
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; // 移除pxItemToRemove
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious; // 保证pxIndex有效
}
pxItemToRemove->pvContainer = NULL; // 设置pvContainer
( pxList->uxNumberOfItems )--; // 计数++
return pxList->uxNumberOfItems; // 返回链表节点个数
}
四、API总结
void vListInitialise( List_t * const pxList ); // 初始化链表
void vListInitialiseItem( ListItem_t * const pxItem ); // 初始化链表节点
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ); // 升序插入链表
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ); // 尾部插入链表
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ); // 移除链表节点
五、链表宏
略,参考源码

浙公网安备 33010602011771号