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 );                    // 移除链表节点

五、链表宏

略,参考源码

posted @ 2025-06-30 18:38  gramming  阅读(292)  评论(0)    收藏  举报