Bootstrap

FreeRTOS列表和列表项 | FreeRTOS七

目录

说明:

一、列表与列表项了解

1.1、简介

1.3、FreeRTOS适用于列表与列表项原因

1.4、列表结构体

1.5、列表结构图

1.6、列表项结构体

1.7、迷你列表项结构体

1.8、列表项结构图

1.9、迷你列表项结构图

1.10、列表插入列表项的实现思路

1.11、列表删除列表项实现思路

二、列表与列表项API函数

2.1、列表初始化函数

2.2、列表项初始化函数

2.3、列表项插入函数

2.4、列表项尾部插入函数

2.5、列表项删除函数

三、列表与列表项示例

3.1、示例

3.2、结果


说明:

关于内容:

1)以下内容多为概念了解与步骤分析

2)暂无个人示例代码,使用的是FreeRTOS的官方示例代码

3)若想移植代码测试的,请移步其它地方寻找,下文内容暂无个人示例代码供测试

关于其它:

1)操作系统:win 10

2)平台:keil 5 mdk

3)语言:c语言

4)板子:STM32系列移植FreeRTOS

一、列表与列表项了解

1.1、简介

        1)列表简介:列表是FreeRTOS中的一个数据结构,概念上与链表类似,列表用来跟踪FreeRTOS中的任务;

        2)列表项简介:列表项就是存放在列表中的项目。

1.2、列表与列表项特点

        1)列表相当于链表,列表项相当于链表中的节点,FreeRTOS中的列表是双向环形链表(头尾相连);

        2)列表特点:列表项间地址非连续,是人为连接在一起的。列表项数目由后期添加个数决定的,可以随时改变(加多少是多少);

        3)数组特点:数组成员地址连续,在最初创建时就觉得了成员数量,并且后期无法改变。

1.3、FreeRTOS适用于列表与列表项原因

        在OS中,任务的数量通常是不确定的,并且任务的状态是会发送改变的,所以使用列表(双向链表)这种结果非常合适。

1.4、列表结构体

typedef struct xLIST
{
    listFIRST_LIST_INTEGRITY_CHECK_VALUE     
    volatile UBaseType_t uxNumberOfItems;
    ListItem_t * configLIST_VOLATILE pxIndex;
    MiniListItem_t xListEnd;                
    listSECOND_LIST_INTEGRITY_CHECK_VALUE   
} List_t;

结构体成员含义:

名称:listFIRST_LIST_INTEGRITY_CHECK_VALUE

含义:检查列表完整性

使用条件:需要配置宏定义configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1,开启以后会向这两个地方分别添加一个变量 xListIntegrityValue1 xListIntegrityValue2,在初始化列表的时候会这两个变量中写入一个特殊的值,默认不开启这个功能。

名称:uxNumberOfItems

含义:用来记录列表中列表项数量

名称:pxIndex

含义:记录当前列表项索引号,用来索引列表

名称:xListEnd

含义:列表中最后一个列表项,用来表示列表结束

1.5、列表结构图

如下图1:

图1

1.6、列表项结构体

struct xLIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE        
    configLIST_VOLATILE TickType_t xItemValue;         
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;   
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
    void * pvOwner;                                    
    struct xLIST * configLIST_VOLATILE pxContainer;   
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE        
};
typedef struct xLIST_ITEM ListItem_t;  

结构体成员含义:

名称:listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE        

含义:检查列表完整性,默认不开启

名称:xItemValue

含义:列表项的值

名称:pxNext

含义:指向下一个列表项

名称:pxPrevious

含义:指向前一个列表项,和pxNext配合起来实现类似双向链表的功能

名称:pvOwner

含义:记录此列表项归谁所有,通常是任务控制块

名称:pxContainer

含义:用来记录此列表项属于哪个列表

1.7、迷你列表项结构体

struct xMINI_LIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
    configLIST_VOLATILE TickType_t xItemValue;
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

结构体成员含义:

名称:xItemValue

含义:列表项的值

名称:pxNext

含义:指向下一个列表项

名称:pxPrevious

含义:指向上一个列表项

1.8、列表项结构图

如下图2:

图12

1.9、迷你列表项结构图

如下图3:

图3

 1.10、列表插入列表项的实现思路

假设一个空链表要插入列表项1(如果存在多个列表项时,要插入列表项,需要比较列表项值xItemValue,按升序排列),如果是插入末尾列表项,要看当前列表的pxindex指向是否是末尾列表项(指向谁,插入谁前面,这时不一定是升序排列),直接进行下列思路进行插入即可。

1)初始化列表与列表项

2)列表的pxNext默认是指向本列表的末尾列表项,现在指向需要进行更改;

3)将pxNext指向列表项1

4)将末尾列表项的pxPrevious指向列表项1

5)列表项1的pxNext指向末尾列表项

6)列表项1的pxPrevious指向pxlndex

7)列表项总数+1

1.11、列表删除列表项实现思路

假设列表中存在列表项1与列表项2,现在要删除列表项2,列表中结构为列表项1->列表项2->末尾列表项;

1)初始化列表与列表项

2)将列表项1的pxNext指向末尾列表项

3)将末尾列表项的pxPrevious指向列表项1

4)列表项总数-1

二、列表与列表项API函数

2.1、列表初始化函数

void vListInitialise( List_t * const pxList )
{
    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
    pxList->xListEnd.xItemValue = portMAX_DELAY;
    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );   
    pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );

    pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

2.2、列表项初始化函数

void vListInitialiseItem( ListItem_t * const pxItem )
{
    pxItem->pxContainer = NULL;
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

2.3、列表项插入函数

void vListInsert( List_t * const pxList,  ListItem_t * const pxNewListItem )
{
    ListItem_t * pxIterator;
    const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
    listTEST_LIST_INTEGRITY( pxList );
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
    if( xValueOfInsertion == portMAX_DELAY )
    {
        pxIterator = pxList->xListEnd.pxPrevious;
    }
    else
    {

        for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );

        pxIterator->pxNext->xItemValue <= xValueOfInsertion;

        pxIterator = pxIterator->pxNext )
        {
        }
    }

    pxNewListItem->pxNext = pxIterator->pxNext;
    pxNewListItem->pxNext->pxPrevious = pxNewListItem;
    pxNewListItem->pxPrevious = pxIterator;
    pxIterator->pxNext = pxNewListItem;


    pxNewListItem->pxContainer = pxList;

    ( pxList->uxNumberOfItems )++;
}

2.4、列表项尾部插入函数


void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
    ListItem_t * const pxIndex = pxList->pxIndex;
    listTEST_LIST_INTEGRITY( pxList );
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
    pxNewListItem->pxNext = pxIndex;
    pxNewListItem->pxPrevious = pxIndex->pxPrevious;
    mtCOVERAGE_TEST_DELAY();

    pxIndex->pxPrevious->pxNext = pxNewListItem;
    pxIndex->pxPrevious = pxNewListItem;
    pxNewListItem->pxContainer = pxList;

    ( pxList->uxNumberOfItems )++;
}

2.5、列表项删除函数

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{

    List_t * const pxList = pxItemToRemove->pxContainer;

    pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
    pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;


    mtCOVERAGE_TEST_DELAY();


    if( pxList->pxIndex == pxItemToRemove )
    {
        pxList->pxIndex = pxItemToRemove->pxPrevious;
    }
    else
    {
        mtCOVERAGE_TEST_MARKER();
    }

    pxItemToRemove->pxContainer = NULL;
    ( pxList->uxNumberOfItems )--;

    return pxList->uxNumberOfItems;
}

三、列表与列表项示例

3.1、示例

暂无

3.2、结果

暂无

;