freertos的帮手---列表

本文深入探讨了FreeRTOS操作系统中任务管理的实现,重点介绍了一个关键组件——列表。列表用于组织任务和线程,文章详细解析了列表结构、列表项及其成员,包括如何创建、插入和移除列表项。通过对列表的理解,可以更好地掌握FreeRTOS的任务调度机制。
摘要由CSDN通过智能技术生成

一.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.

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

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值