我是靠谱客的博主 阳光老师,最近开发中收集的这篇文章主要介绍freertos的帮手---列表,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一.freertos是实时操作系统.谈到系统,你能想到什么...不需要过多的脑补,任务和线程组织,调度,切换.

系统如何组织,如何调度,如何切换?这就像一个城市的运转一样,其实都一样.

这篇文章先来谈谈组织这件事. 

组织什么?无非是任务或者线程?什么是线程,我们姑且当做是路人甲已丙丁.

那么甲乙丙丁如何组织了,有请重要的嘉宾出场---列表

what,s 列表???

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和listSECOND_LIST_INTEGRITY_CHECK_VALUE是列表完整检查项,类似你家大门的锁,查看是否列表被破坏.

uxNumberOfItems表示列表有几个成员

pxIndex是一个指针,指向列表项.对于列表而言永远指向xListEnd成员?为什么,接着看看呗

xListEnd是列表项的兄弟,缺胳膊少腿.

那我们看下列表项是啥玩意>>

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;                    /* For some reason lint wants this as two separate definitions. */

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;

列表项的兄弟比列表项少了pvOwner和pxContainer成员.

xItemValue表示列表项记录的数值.嗯,什么数值,对于线程那说可能是优先级吗?利用他来排序,很有可能.

pxNext和pxPrevious是列表指针

pvOwner表示一个void *.从名字看有归属的意思,归属任务还是什么?

pxContainer一个列表指针

了解完成员,列表项兄弟和列表项区别在哪?列表项兄弟要偷懒了,他不干活(没有归属,没有列表),猜测下-可能是个标识

接下来,看看你们有什么神通广大.

 

二.无非就是创建,删除,链表当然有插入和移除咯.

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 );
}

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.插入.

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 )++;
}

首先找到插入点,插入点根据xValueOfInsertion得到.升序排列.

然后直接插入,再把当前的列表项指向列表.最后列表成员加1.

3.移除

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;
}

移除也很简单.

 

三:思考与总结

列表通过列表项的xItemValue链接起来,并且每个列表项有一个指向列表的指针,通过这个指针可以快速定位到列表,以便快速获取首位列表项,从而进行下一步操作.

列表项还有一个pvOwner成员.到这里猜测是指向某个事物,比如任务,队列,timer.

那么通过列表,查找到列表项,然后在找到具体事物,思路渐渐变得清晰起来.

 

 

 

 

最后

以上就是阳光老师为你收集整理的freertos的帮手---列表的全部内容,希望文章能够帮你解决freertos的帮手---列表所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部