FreeRTOS ~(五)队列的常规使用 ~ (5/5)队列集

news2024/9/23 23:24:37

举例子说明:队列集的使用

队列集:Queue Set
多个队列的集合,一个队列中依次存放多个队列的句柄

一般使用API的流程如下:
1.创建几个队列
2.创建队列集
3.把这几个队列添加进队列集中
然后可以创建任务去使用队列和队列集
static  QueueHandle_t     xQueueHandle1;  /* 队列1的句柄 */
static  QueueHandle_t     xQueueHandle2;  /* 队列2的句柄 */
static  QueueSetHandle_t  xQueueSet;      /* 队列集的句柄 */

/* 使用API创建队列集的过程 */
void UseQueueSetStep(void)
{
	/* Step1. 创建2个queue ------------------------*/
	xQueueHandle1 = xQueueCreate(2, sizeof(int));
	if (xQueueHandle1 == NULL)
	{
		printf("can not create queue 1 \r\n");
	}
	
	xQueueHandle2 = xQueueCreate(2, sizeof(int));
	if (xQueueHandle2 == NULL)
	{
		printf("can not create queue 2 \r\n");
	}
	
	/* Step2. 创建queue set ----------------------*/
	xQueueSet = xQueueCreateSet(4);
	/* 注意:这里队列集合的长度为什么是4?
       当前队列集要监测2个队列A,B;
       队列集的长度是:队列A的长度+队列B的长度
	   所以这里的长度应该是2+2=4 */
	   
	/* Step3. 把2个queue添加进queue set -----------*/
	xQueueAddToSet(xQueueHandle1, xQueueSet);
	xQueueAddToSet(xQueueHandle2, xQueueSet);
}

/* Task1:往队列里写一个int类型的值,且这个值伴随Task1的每次执行从0开始自增 */
void Task1Function(void * param)
{
	int i = 0;
	while (1)
	{
		xQueueSend(xQueueHandle1, &i, portMAX_DELAY);
		i++;
		vTaskDelay(10);
	}
}

/* Task2:往队列里写一个int类型的值,且这个值伴随Task1的每次执行从-1开始自减 */
void Task2Function(void * param)
{
	int i = -1;
	while (1)
	{
		xQueueSend(xQueueHandle2, &i, portMAX_DELAY);
		i--;
		vTaskDelay(20);
	}
}

/* Task3:使用队列集监测Queue1和Queue2哪个队列有数据,就将该队列中的数据打印出来 */
void Task3Function(void * param)
{
	QueueSetMemberHandle_t handle;
	int i;
	while (1)
	{
		/* Step1:读取 加入队列集中的所有队列里 哪个队列有数据,
		          返回该队列的句柄 等待时长为最大时长 */
		handle = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);

		/* Step2:读队列 由于Step1已经知道哪个队列有数据了,
		          因此,这里就是正常的读队列操作,只是超时时间可以直接设置为0,
		          因为能执行到这里,说明该队列里肯定是有数据的,无须等待,因此写0. */
		xQueueReceive(handle, &i, 0);

		/* Step3:打印数据 */
		printf("get data : %d\r\n", i);
	}
}

int main( void )
{
	prvSetupHardware();
	
	UseQueueSetStep();
	
	/* 创建3个任务,来体验队列和队列集的使用 */
	xTaskCreate(Task1Function, "Task1", 100, NULL, 1, NULL);
	xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
	xTaskCreate(Task3Function, "Task3", 100, NULL, 1, NULL);

	vTaskStartScheduler();
	return 0;
}
从上述的代码中可以分析的是:
1.Task1、Task2、Task3三个任务的优先级均一致且优先级均大于0,因此任务调度器开启后,先执行的任务是Task3,
  而后是Task1和Task2,后续的顺序将会因为Task1和Task2的延时不同有所调整.
2.那么可以猜想,Task3先执行,但是由于Task1与Task2均未执行,没有向队列中写入数据,那么Task3监测的队列集中
  也不会有数据,因此Task3最开始第一次执行任务的时候是不会有数据打印的;
  当Tick中断到来的时候,切换了Task1,Task1向Queue1中写入了值是0,然后自增,那么同时写队列这个操作也会将
  Queue的句柄写入队列集中,那么后面再次执行到Task3的时候就会打印出来数据是0;
  当Tick中断再次到来,切换为了Task2,Task2向Queue2中写入了值是-1,然后自减,那么同时写队列这个操作也会将
  Queue的句柄写入队列集中,那么后面再次执行到Task3的时候就会打印出来数据是-1;
  当Tick中断再次到来,切换为了Task3,这时候读队列集,发现有数据,依次读取,第一次读取是Queue1的0,打印0,然
  后再次读取是Queue2的-1,打印-1.
  
Debug看一下串口打印的结果是否和理论推到一致,如下图:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/732305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[MySQL]可重复读下的幻读

一、幻读的定义 根据MySQL官网的描述,幻读是“相同的查询在不同时间返回了不同的结果” The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. 同时官网还举例说明了,如…

图形学 | 期末复习(上)| games101笔记 | 补档

博客基于GAMES101-现代计算机图形学入门-闫令琪,但不是其完整笔记,基于复习要求有一定的删减。考试以图形学入门基本概念和核心研究内容为主,少量公式。即以论述概念为主,涉及少量算法。p1:29:12是对应的games101视频节点&#xf…

maven在vscode添加依赖操作

1.maven查找依赖 点击进入网站,搜索需要的依赖包名选择一个合适的依赖 根据自己需要选择版本 选中maven,复制好代码,粘贴到pom.xml 2. 添加新的依赖 在pom.xml文件中,添加了依赖后,打开vscode终端,输入以…

matlab解微分方程

1.匿名函数 1.1创建 f(变量) 表达式; f(x1,x2) x1.^2x2;1.2 求解 x1为2 3 4 5;x2为3 4 5 6的情况下求解函数f的值 f(x1,x2) x1.^2x2; yf(2:5,3:6); subplot(121);%选择子图位置 plot(y)%画图2.一阶微分方程 用“dsolve” 2.1例 y.-y0 step1: 申明自变量和因…

一文2000字从0到1用Jmeter全流程性能测试实战

项目背景: 我们的平台为全国某行业监控平台,经过3轮功能测试、接口测试后,98%的问题已经关闭,决定对省平台向全国平台上传数据的接口进行性能测试。 01、测试步骤 1、编写性能测试方案 由于我是刚进入此项目组不久&#xff0c…

Linux--调试器:gdb

gcc与g默认动态链接形成的可执行程序(比如a.out)是release 版本,不可调试!!! 如何搞成debug可调试版本? gcc 程序名 -o 可执行程序名 -g //添加了-g就表明该程序是debug方式发布的 查看可执行…

归并排序和基数排序包含完整程序和结果

一,归并排序 1.定义:将两个或者两个以上的有序表合并成一个新的游戏表的过程。 2路归并排序:假设排序表中有n个记录,则可以将其视为n个有序子表,每个子表的长度为1,然后两两合并,得到n/2&…

前端vue入门(纯代码)24_Modules

穷不怪父,苦不责妻,方为真男人! 【23.Vuex中的模块化和命名空间】 [可以去官网看看Vuex3文档](Module | Vuex (vuejs.org)) 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,sto…

SQLServer2005位安装教程(图解)

进入下载的文件中,双击打开 :splash.hta 文件进行安装 根据自己的系统来选择性进行安装,这里我们选择第二项:基于 x64 的操作系统(6)。 然后在安装中选择“服务器组件、工具、练级丛书和示例©”的选项进行安装。 此处的注册信息可以忽略,非必填选项

第二章 模型评估和选择

文章目录 第二章 模型评估和选择2.1经验误差与过拟合2.2评估方法2.2.1留出法2.2.2交叉验证法2.2.3自助法2.2.4调参与最终模型 2.3性能度量2.3.1错误率与精度2.3.2查准率、查全率和F12.3.3ROC与AUC2.3.4代价敏感错误率与代价曲线 第二章 模型评估和选择 2.1经验误差与过拟合 通…

Unity-3d小游戏开发-----走迷宫

本人是在学习完c,c,数据结构算法,操作系统网络这些基础的课程之后,打算学习自己喜欢的游戏开发方向的东西,然后在B站上自学了几天unity,用到unity的触发器,碰撞,刚体,以及…

图像处理入门教程:从Python到Opencv

Python编程 这里主要针对有一定基础的读者,在Python编程中,掌握基础语法和数据类型是非常重要的。它们是构建程序的基石,是提供解决问题和开发应用的工具。在这里,我将简单介绍一些常用的语法和数据类型。 一、环境搭建 详细请…

14 - 信号优先级与安全性

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接:(更新中)Linux系统编程训练营 - 目录 文章目录 1. 信号优先级1.1 问题1.2 信号优先级的概念1.3 信号优先级实验设计1.3.1 发送端1.3.2 接收端1.3.3 编程实验:信号优先级实验 …

普通索引VS唯一索引

查询性能 假设 我们有一列int 类型的value 对它进行查询 (VALUE无重复字段) SELECT value FROM table where value 8; 如过是普通索引 找到value 8 的记录后还会继续找,直到碰到第一个不满足 k5 条件的记录。 如过是唯一索引 找到value 8这条记录就不会往下找…

百望股份高级PMO专家赵雅婧受邀为第十二届中国PMO大会演讲嘉宾

百望股份有限公司项目管理部高级PMO专家赵雅婧女士受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾,演讲议题:PMO的组织建设与持续运营。大会将于8月12-13日在北京举办,敬请关注! 议题简要: 众所周知&#xff…

图像全景拼接

TODO: 实现图片的全景拼接 流程: (1)检测左右2图片的SIFT关键特征点,并计算特征描述 (2)使用KNN检测来自左右2图的SIFT特征,进行匹配 (3)计算视角变换矩阵H&#xff0c…

目标跟踪基础:距离度量

本文来自公众号“AI大道理” —————— 距离度量在CV 、NLP以及数据分析等领域都有众多的应用。 距离度量可以当做某种相似度,距离越近,越相似。 在目标跟踪领域中,需要判断目标之间的距离或相似度,从而判断前后帧的目标是否…

Redis实战案例13-集群下的并发安全问题

在解决一人一单的问题上面,采用了悲观锁的方案,但是这种方案只适合单机情况,在集群的模式下就不适用了; 覆盖yaml文件中的端口号 修改nginx中conf,这样就可以反向代理到两个节点上去,轮询的负载均衡规则&am…

git bash---打开当前路径所在文件夹

0 Preface/Foreword 在Windows操作系统中使用git bash时,可以通过命令直接打开当前路径下的文件夹,命令如下 explorer .

MS17-010漏洞复现

官方描述:Microsoft Security Bulletin MS17-010 - Critical | Microsoft Learn漏洞描述: Microsoft Windows SMB Server远程代码执行漏洞,Microsoft Server Message Block 1.0 (SMBv1)服务器处理某些请求时,在实现上存在远程代码…