FreeRTOS开发实战_链表管理

19 篇文章 2 订阅
5 篇文章 2 订阅

4.1 链表的特性

在FreeRTOS的链表管理中,采用的是双向链表,其中链表头指针使用xLIST来表示,而链表尾部指针为xMINI_LIST_ITEM。

这个链表有一个非常巧妙的设计在于添加了两个item:

  • pvContainer,用来记录这个Item是属于哪一个链表;
  •  pvOwner,用来扩展Item,可以用来基于链表做客制化的操作;

比如我们客制化的一个链表Item

typedef struct _Rpmsg_Listener

{

      RpmsgCallbackFunction_t pxCallbackFunction;

      RpmsgSendFunction_t pxSendFunction;

      ListItem_t  xRpmsgListenerListItem;

      RpmsgEvent_t *mEvent;

}RpmsgListener_t;

 刚刚初始化表头后的链表形态如下:

插入Item之后的链表结构如下图:

4.1.1 数据存储

4.1.1.1 表头指针

/*

 * Definition of the type of queue used by the scheduler.

 */

typedef struct xLIST

{

        configLIST_VOLATILE UBaseType_t uxNumberOfItems;

        ListItem_t * configLIST_VOLATILE pxIndex;             /*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */

        MiniListItem_t xListEnd;                                             /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */

} List_t;

  • l  uxNumberOfItems:记录链表的ITEM数目;
  • l  pxIndex:链表游标
  • l  xListEnd:队尾标志

4.1.1.2 链表表项

/*

 * Definition of the only type of object that a list can contain.

 */

struct xLIST_ITEM

{

        configLIST_VOLATILE TickType_t xItemValue;                  /*< The value being listed.  In most cases this is used to sort the list in descending order. */

        struct xLIST_ITEM * configLIST_VOLATILE pxNext;         /*< Pointer to the next ListItem_t in the list. */

        struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;   /*< Pointer to the previous ListItem_t in the list. */

        void * pvOwner;                                                                                    /*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */

        void * configLIST_VOLATILE pvContainer;                                 /*< Pointer to the list in which this list item is placed (if any). */

};

  • l  xItemValue:表项数值,常用于链表排序;
  • l  pxNext:指针,指向下一个;
  • l  pxPrevious:指针,指向前一个;
  • l  pvOwner:指针,常指向TCB;
  • l  pvContainer:指针,常指向链表表头。

4.2 使用链表

4.2.1 初始化链表

voidvListInitialise( List_t * const pxList )

参数:

  • pxList:链表表头指针

4.2.2 初始化表项

voidvListInitialiseItem( ListItem_t * const pxItem )

参数:

  • pxItem:链表表项

4.2.3 插入表项

voidvListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )

参数:

  •  pxList:需要插入的链表
  • pxNewListItem:链表项目

4.2.4 链表尾部插入

void vListInsertEnd(List_t * const pxList, ListItem_t * const pxNewListItem )

参数:

  • pxList:需要插入的链表
  • pxNewListItem:链表项目

4.2.5 移除表项

UBaseType_tuxListRemove( ListItem_t * const pxItemToRemove )

参数:

  • pxItemToRemove :需要移除的表项

4.2.6 其他宏定义操作

  • l  listSET_LIST_ITEM_VALUE

设置Item Value

  • l  listSET_LIST_ITEM_OWNER

设置List Owner

  • l  listCURRENT_LIST_LENGTH

当前链表的长度

  • l  listGET_LIST_ITEM_OWNER

取得链表的Owner

4.3 使用实例

 

typedef struct _Sensor_Event_

{

    Sensor mSenor;

    float values[4];

}SensorEvent_t;

/*

 * Defines the prototype to which timer callback functions must conform.

 */

typedef void (*SensorCallbackFunction_t)(SensorEvent_t * mListener);

 

typedef struct _Sensor_Listener

{

      int mSensorType;

      SensorCallbackFunction_t pxCallbackFunction;

      ListItem_t  xSensorListenerListItem;

      SensorEvent_t *mEvent;

}SensorListener_t;

 

void ap_RegisterSensorListener(int RegiterID,int mSensorType,SensorCallbackFunction_t mpxCallbackFunction,SensorEvent_t* mEvent)

{

    //Create the new Sensor Listener

    SensorListener_t *pxNewSensorListener;

    pxNewSensorListener =(SensorListener_t *)pvPortMalloc( sizeof( SensorListener_t ) );

    pxNewSensorListener->mSensorType = mSensorType;

    pxNewSensorListener->pxCallbackFunction = mpxCallbackFunction;   

    pxNewSensorListener->mEvent=mEvent;

    vListInitialiseItem( &( pxNewSensorListener->xSensorListenerListItem ) );

   

#ifdef SUPPORT_GSENSOR

    //Add the new Item to the list by the Sensor Type

    if(mSensorType == TYPE_GYROSCOPE)

    {

        listSET_LIST_ITEM_VALUE( &( pxNewSensorListener->xSensorListenerListItem ), RegiterID );

        listSET_LIST_ITEM_OWNER( &( pxNewSensorListener->xSensorListenerListItem ), pxNewSensorListener );

        vListInsert( &xGsensorList, &( pxNewSensorListener->xSensorListenerListItem ) );

    }

#endif

   PRINTF("The xGsensorList length is %d\n",listCURRENT_LIST_LENGTH(&xGsensorList));

}

 

void mw_sensor_init(void)

    //Add Listener List for Sensor Listenor

#ifdef SUPPORT_GSENSOR

    vListInitialise( &xGsensorList );

#endif

}

 

#ifdef SUPPORT_GSENSOR

//Called by the HAL_Sensor

void OnGyroSensorChangedCallBack(float Gxf, float Gyf,float Gzf)

{

    List_t * pxConstList;

    SensorListener_t* vSensorListener;

    pxConstList = &xGsensorList;

    pxConstList->pxIndex = pxConstList->pxIndex->pxNext;       

    while(( void * ) ( pxConstList )->pxIndex != ( void * ) &( ( pxConstList )->xListEnd ))

    {

         vSensorListener = (SensorListener_t *)listGET_LIST_ITEM_OWNER( ( pxConstList )->pxIndex );

         vSensorListener->mEvent->values[0] = Gxf;

         vSensorListener->mEvent->values[1] = Gyf;

         vSensorListener->mEvent->values[2] = Gzf;

         vSensorListener->pxCallbackFunction( ( SensorEvent_t *) vSensorListener->mEvent);

         pxConstList->pxIndex = pxConstList->pxIndex->pxNext;      

    }

}

#endif

 

BaseType_t ap_unRegisterSensorListener(int RegiterID,int mSensorType)

{

    SensorListener_t* vSensorListener;

    List_t * pxConstList;

    if(mSensorType == TYPE_GYROSCOPE)

    {

        pxConstList = &xGsensorList;

    }else

    {

        return pdFAIL;

    }

    while( (( pxConstList )->pxIndex->xItemValue == RegiterID)

          &&(( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )

          )

    {

          ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                                                       

    }

    if(( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )

    {

        return pdFAIL;

    }

    vSensorListener = (SensorListener_t *)listGET_LIST_ITEM_OWNER( ( pxConstList )->pxIndex );

    ( void ) uxListRemove(&(vSensorListener->xSensorListenerListItem));

    vPortFree(vSensorListener);

    return pdPASS;  

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值