freeRtos源码分析之核心数据结构链表

FreeRtos源码分析核心数据结构链表

1.常见链表类型

​ 什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

1.1单链表

struct List
{
    type data;
    struct list *next;
};

freeRtos源码分析之核心数据结构链表_第1张图片

1.2单向循环链表

freeRtos源码分析之核心数据结构链表_第2张图片

1.3双向链表

freeRtos源码分析之核心数据结构链表_第3张图片

1.4双向循环链表

freeRtos源码分析之核心数据结构链表_第4张图片

2.freeRtos中的链表

2.1定义

使用Source Insight 打开freeRtos源码,在list.h文件中定义freeRtos中的基本数结构。如下图所示
freeRtos源码分析之核心数据结构链表_第5张图片
其中struct xMINI_LIST_ITEM是最小的链表元素,是一个双向链表的结构。struct xLIST_ITEM 和typedef struct xLIST是后面用于任务调度和处理的基本数据结构。至于其中每项的意思在后面会做解释。

2.2操作

#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链表主要实现了初始化,在合适位置插入和删除指定节点这几个主要函数。

2.2.1链表初始化

freeRtos源码分析之核心数据结构链表_第6张图片
该初始化函数,初始了一个双向循环链表,所有指针域都指向了自己。

2.2.2通过protMax_DELAY插入到指定位置

freeRtos源码分析之核心数据结构链表_第7张图片

  • 第一步定义一个临时节点ListItem_t * pxIterator,也就是待插入位置的前一个节点。
  • 第二步将带插入节点指向当前节点的下一个节点。
  • 第三步将待插入节点的下一个节点前驱指向自己,此时也就是当前节点的下一个节点的前驱指向待插入节点。
  • 第四步将待插入节点的前驱指向当前节点。
  • 第五步当前节点的下一个节点指向待插入节点。

步骤图如下
freeRtos源码分析之核心数据结构链表_第8张图片
这个函数的功能就是确保每个任务都获得相同的CPU时间片。

2.2.3尾插

freeRtos源码分析之核心数据结构链表_第9张图片

2.2.4删除指定节点

freeRtos源码分析之核心数据结构链表_第10张图片

2.3总结

在freeRtos中list.c和list.h定义了freeRtos的基本数据结构链表,这是一个双向循环链表,实现了一些基本操作函数,方便后续任务的创建以及调度管理。

你可能感兴趣的:(RTOS,数据结构,链表,windows,stm32,单片机)