FreeRTOS列表
内核中有很多双向列表,这些列表可以挂接很多列表项,每条列表都有一个确定的尾节点、列表当前指针、列表项个数
/* 列表结构体 */
typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUE configLIST_VOLATILE UBaseType_t uxNumberOfItems; /* 列表项个数 */ListItem_t *configLIST_VOLATILE pxIndex; /* 当前列表项指针 */MiniListItem_t xListEnd; /* 列表的尾节点 */listSECOND_LIST_INTEGRITY_CHECK_VALUE
}List_t;
列表尾节点中的有效信息包括:列表项的值、next指针、previous指针
/* 迷你列表项结构体 */
struct xMINI_LIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUEconfigLIST_VOLATILE TickType_t xItemValue; /* 列表项的值 */struct xLIST_ITEM *configLIST_VOLATILE pxNext; /* next指针指向后一个列表项 */struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; /* previous指针指向前一个列表项 */
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;
列表项的内容包括:列表项的值、next指针、previous指针、所属TCB指针、正在挂接的列表指针
/* 列表项结构体 */
struct xLIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE configLIST_VOLATILE TickType_t xItemValue; /* 列表项的值 */struct xLIST_ITEM *configLIST_VOLATILE pxNext; /* next指针指向后一个列表项 */struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; /* previous指针指向前一个列表项 */void *pvOwner; /* 该指针指向所属TCB */void *configLIST_VOLATILE pvContainer; /* 指向包含该列表项的列表 */listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};
typedef struct xLIST_ITEM ListItem_t;
列表会挂接很多列表项,如图所示:
列表初始化时不包含任何列表项
/* 功能:初始化列表pxList:列表指针 */
void vListInitialise(List_t *const pxList)
{/* 列表初始化时只有尾节点,因此将当前指针指向尾节点 */pxList->pxIndex = (ListItem_t *)&(pxList->xListEnd);/* 尾节点的值初始化为0xffffffff */pxList->xListEnd.xItemValue = portMAX_DELAY;/* 列表初始化时只有尾节点,且列表是双向环形链表 */pxList->xListEnd.pxNext = (ListItem_t *)&(pxList->xListEnd);pxList->xListEnd.pxPrevious = (ListItem_t *)&(pxList->xListEnd);/* 列表项的个数初始化为0 */pxList->uxNumberOfItems = (UBaseType_t)0U;listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList);listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList);
}
初始化完成后,如图所示:
列表项初始化时不属于任何列表
/* 功能:初始化列表项pxItem:列表项指针 */
void vListInitialiseItem(ListItem_t *const pxItem)
{/* 将列表项所属列表指针初始化为不指向任何列表 */pxItem->pvContainer = NULL;listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem);listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem);
}
列表初始化后,如图所示:
列表项插入列表的方式有两种,一种是直接插入当前指针指向的位置,另一种是按照列表项值从小到大插入
/* 功能:将列表项插入列表pxList:列表指针pxNewListItem:列表项指针 */
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->pvContainer = (void *)pxList;/* 列表中列表项个数加一 */(pxList->uxNumberOfItems)++;
}/* 功能:将列表项按列表值从小到大插入列表中pxList:列表指针pxNewListItem:列表项指针 */
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->pvContainer = (void *)pxList;/* 列表中列表项个数加一 */(pxList->uxNumberOfItems)++;
}
从列表中移除列表项
/* 功能:将列表项从当前所在的列表中移除pxItemToRemove:列表项返回值:移除该列表项后所在列表中列表项的个数 */
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove)
{/* 列表项所在列表指针 */List_t *const pxList = (List_t *)pxItemToRemove->pvContainer;/* 将列表项从列表中移除 */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->pvContainer = NULL;/* 列表中列表项个数减一 */(pxList->uxNumberOfItems)--;/* 返回列表项个数 */return pxList->uxNumberOfItems;
}
列表还提供了一些其他的接口
/* 设置列表项所属TCB */
#define listSET_LIST_ITEM_OWNER(pxListItem, pxOwner) ((pxListItem)->pvOwner = (void *)(pxOwner))/* 获取列表项所属TCB */
#define listGET_LIST_ITEM_OWNER(pxListItem) ((pxListItem)->pvOwner)/* 设置列表项值 */
#define listSET_LIST_ITEM_VALUE(pxListItem, xValue) ((pxListItem)->xItemValue = (xValue))/* 获取列表项值 */
#define listGET_LIST_ITEM_VALUE(pxListItem) ((pxListItem)->xItemValue)/* 获取列表头部列表项的值 */
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY(pxList) (((pxList)->xListEnd).pxNext->xItemValue)/* 获取列表头部列表项 */
#define listGET_HEAD_ENTRY(pxList) (((pxList)->xListEnd).pxNext)/* 获取下一个列表项 */
#define listGET_NEXT(pxListItem) ((pxListItem)->pxNext)/* 获取列表尾节点 */
#define listGET_END_MARKER(pxList) ((ListItem_t const *)(&((pxList)->xListEnd)))/* 判断列表是否为空 */
#define listLIST_IS_EMPTY(pxList) ((BaseType_t)((pxList)->uxNumberOfItems == (UBaseType_t)0))/* 获取列表中当前列表项的个数 */
#define listCURRENT_LIST_LENGTH(pxList) ((pxList)->uxNumberOfItems)/* 将当前列表项指针指向下一个列表项,返回所属TCB */
#define listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList) \
{ \List_t *const pxConstList = (pxList); \(pxConstList)->pxIndex = (pxConstList)->pxIndex->pxNext; \if((void *)(pxConstList)->pxIndex == (void *)&((pxConstList)->xListEnd)) \{ \(pxConstList)->pxIndex = (pxConstList)->pxIndex->pxNext; \} \(pxTCB) = (pxConstList)->pxIndex->pvOwner; \
}/* 获取列表首节点所属TCB */
#define listGET_OWNER_OF_HEAD_ENTRY(pxList) ((&((pxList)->xListEnd))->pxNext->pvOwner)/* 判断列表项是否属于指定列表 */
#define listIS_CONTAINED_WITHIN(pxList, pxListItem) ((BaseType_t)((pxListItem)->pvContainer == (void *)(pxList)))/* 获取列表项所在列表 */
#define listLIST_ITEM_CONTAINER(pxListItem) ((pxListItem)->pvContainer)/* 判断列表是否已经初始化(尾节点列表项值为最大可能值0xffffffff) */
#define listLIST_IS_INITIALISED(pxList) ((pxList)->xListEnd.xItemValue == portMAX_DELAY)
FreeRTOS列表相关推荐
- 【STM32】FreeRTOS列表和列表项详解
00. 目录 文章目录 00. 目录 01. 概述 02. 列表 03. 列表项 04. 列表相关宏 05. 列表相关函数 5.1 初始化列表 5.2 初始化列表项 5.3 列表项插入函数 5.4 列 ...
- 【STM32】FreeRTOS列表应用示例
00. 目录 文章目录 00. 目录 01. 概述 02. 任务设计 03. 相关设置 04. 程序设计 05. 实验结果 06. 附录 07. 参考 01. 概述 掌握FreeRTOS中列表和列表项 ...
- 【STM32】FreeRTOS 列表和列表项
文章目录 main.c main.c
- FreeRTOS内核实现01:列表与列表项实现
目录 1. FreeRTOS编程风格 1.1 数据类型 1.2 变量名 1.3 函数名 1.4 宏 2. FreeRTOS列表实现分析 2.1 列表项数据类型 2.2 迷你列表项数据类型 2.3 列表 ...
- 【连载】从单片机到操作系统⑥——FreeRTOS任务切换机制详解
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! 前言 FreeRTOS是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了FreeRTOS,则避免 ...
- 正点原子FreeRTOS(上)
更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入------ ...
- HAL库版FreeRTOS(上)
目录 FreeRTOS 简介 初识FreeRTOS 什么是FreeRTOS? 为什么选择FreeRTOS? FreeRTOS 的特点 商业许可 磨刀不误砍柴工 查找资料 FreeRTOS 官方文档 C ...
- FreeRTOS任务相关API函数---查询/改变某个任务的优先级+获取全部/某个任务状态信息
本文是<ALIENTEK STM32F429 FreeRTOS 开发教程>第十一章学习笔记 第一章笔记–FreeRTOS简介与源码下载 第二章笔记–FreeRTOS在STM32F4上移植 ...
- FreeRTOS任务创建
本文是<ALIENTEK STM32F429 FreeRTOS 开发教程>第八章学习笔记-1 第一章笔记–FreeRTOS简介与源码下载 第二章笔记–FreeRTOS在STM32F4上移植 ...
最新文章
- IIS 的负载均衡【IIS7.0以上才可以使用】---- Application Request Routing(ARR)
- 排序算法系列:Shell 排序算法
- CSS3 总结(一)
- Elasticsearch7.15.2 ik中文分词器 定制化分词器之扩展词库(远程)
- js请求后台接口返回的图片并转为base64
- CSS和CSS3中的伪元素和伪类(总结)
- XML非法字符的处理
- extern ,extern C 与 __cplusplus
- 使用python学习数学建模
- java lambda函数_Java中的Lambda函数
- c 语言鼠标钩子,线程钩子(鼠标钩子) | C/C++程序员之家
- 登录harbor时的SSL异常: x509: certificate is valid for ingress.local
- 看完即会,抓取微信小程序数据包教程
- html京东下拉菜单设置,实现京东导航栏的下拉框
- UI设计色彩模式选择
- java二重积分_《University Calculus》-chaper13-多重积分-二重积分的计算
- 燕十八PHP高性能架构班教学视频教程
- 各种神奇网站集合(持更)
- iOS开发——项目篇—高仿百思不得姐
- 10种排序算法比较(直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、归并排序、基数排序、折半插入排序、2路插入排序)
热门文章
- QSettings生成以及解析配置文件
- Qt工作笔记-QGraphics框架中,给图像中的点连线【获取场景中的数据】【有坑】
- java题-如何递归遍历一个文件夹下的所有文件
- HTML期末作业-宠物网
- c语言打印删除空格,新人提问:如何将输出时每行最后一个空格删除
- firefox使用掘金插件_久等了,这款知名浏览器下载插件终于上线Chrome版本!
- nodejs获得服务器响应,轻松创建nodejs服务器(6):作出响应
- mysql21_mysql2
- python property函数_Python内置函数property()如何使用
- qq空间登陆 cookie_把这篇 Session、Cookie、Token看完,和面试官随便谈人生