热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FreeRTOS开发实战_链表管理

4.1链表的特性在FreeRTOS的链表管理中,采用的是双向链表,其中链表头指针使用xLIST来表示,而链表尾部指针为xMINI_LIST_ITEM。这个链表有一个非常巧妙的设计在

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;

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

FreeRTOS开发实战_链表管理

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

FreeRTOS开发实战_链表管理

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;             /*

        MiniListItem_t xListEnd;                                             /*

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

        struct xLIST_ITEM * configLIST_VOLATILE pxNext;         /*

        struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;   /*

        void * pvOwner;                                                                                    /*

        void * configLIST_VOLATILE pvContainer;                                 /*

};

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

}



推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 工作经验谈之-让百度地图API调用数据库内容 及详解
    这段时间,所在项目中要用到的一个模块,就是让数据库中的内容在百度地图上展现出来,如经纬度。主要实现以下几点功能:1.读取数据库中的经纬度值在百度上标注出来。2.点击标注弹出对应信息。3 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 本文介绍了PHP常量的定义和使用方法,包括常量的命名规则、大小写敏感性、全局范围和标量数据的限制。同时还提到了应尽量避免定义resource常量,并给出了使用define()函数定义常量的示例。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
author-avatar
燕子的世界是什么
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有