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

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

1.常见链表类型

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

1.1单链表

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

在这里插入图片描述

1.2单向循环链表

在这里插入图片描述

1.3双向链表

在这里插入图片描述

1.4双向循环链表

在这里插入图片描述

2.freeRtos中的链表

2.1定义

使用Source Insight 打开freeRtos源码,在list.h文件中定义freeRtos中的基本数结构。如下图所示
在这里插入图片描述
其中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链表初始化

在这里插入图片描述
该初始化函数,初始了一个双向循环链表,所有指针域都指向了自己。

2.2.2通过protMax_DELAY插入到指定位置

在这里插入图片描述

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

步骤图如下
在这里插入图片描述
这个函数的功能就是确保每个任务都获得相同的CPU时间片。

2.2.3尾插

在这里插入图片描述

2.2.4删除指定节点

在这里插入图片描述

2.3总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值