【复习笔记】FreeRTOS(六) 队列操作

本文是FreeRTOS复习笔记的第六节,队列操作。

上一篇文章: 【复习笔记】reeRTOS(四) 列表项的插入和删除

文章目录

  • 1.队列操作
    • 1.1.队列操作过程
    • 1.2.队列操作常用的API函数
  • 二、实验设计
  • 三、测试例程
  • 四、实验效果


1.队列操作

队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。任务与任务、任务与中断之间要交流的数据保存在队列中,叫做队列项目。队列所能保存的最大数据项目数量叫做队列的长度,创建队列的时候会指定数据项目的大小和队列的长度。由于队列用来传递消息的,所以也称为消息队列。

1.1.队列操作过程

创建队列
在这里插入图片描述
上图中任务 A 要向任务 B 发送消息,这个消息是x 变量的值。首先创建一个队列,并且指定队列的长度和每条消息的长度。这里我们创建了一个长度为 4 的队列,因为要传递的是x值,而x是个 int类型的变量,所以每条消息的长度就是 int 类型的长度,在 STM32 中就是4字节,即每条消息是 4 个字节的。
向队列发送第一个消息
在这里插入图片描述
上图中任务A的变量x值为10,将这个值发送到消息队列中。此时队列剩余长度就是3了。队列中发送消息是采用拷贝的方式,所以一旦消息发送完成变量x就可以再次被使用,赋其他的值。
向队列发送第二个消息
在这里插入图片描述
上图中任务 A 又向队列发送了一个消息,即新的x 的值,这里是 20。此时队列剩余长度为 2。
从队列中读取消息
在这里插入图片描述
上图中任务 B 从队列中读取消息,并将读取到的消息值赋值给 y,这样 y 就等于 10了。任务 B 从队列中读取消息完成以后可以选择清除掉这个消息或者不清除。当选择清除这个消息的话其他任务或中断就不能获取这个消息了,而且队列剩余大小就会加一,变成 3。如果不清除的话其他任务或中断也可以获取这个消息,而队列剩余大小依旧是 2。

队列的内容除了队列的创建、队列的出队、入队函数、队列的环形缓冲区的实现,还有数据的拷贝、先进先出、以及后进先出的实现、队列锁、以及队列任务级函数与中断级函数的区别等知识。

由于队列的知识也比较多,这里只是进行一个简单的使用,学会队列的基本操作。

1.2.队列操作常用的API函数

函数名称作用
xQueueCreate()动态创建队列
xQueueCreateStatic()静态创建队列
xQueueSend()队列数据发送
xQueueReceive()队列数据接收

二、实验设计

实验目的:学会对FreeRTOS 简单队列操作
实验设计:设计两个任务: task1 task 和 task2 task ,其中 task1 task 和 task2 task的任务优先级相同,这三个任务的任务功能如下:

  • task1 task :发送一串字符
  • task2 task :接收任务1的字符

三、测试例程

主函数 main.c代码如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"/*使用结构体储存数据*/
struct QueuePrint
{uint8_t Tick;char Data[20];
};QueueHandle_t myPrintfQueue;void task1_task(void *p); //任务函数
void task2_task(void *p); //任务函数int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4delay_init(168);		//初始化延时函数uart_init(115200);     	//初始化串口LED_Init();		        //初始化LED端口/*动态创建队列,2个队列项目,一个发送一个接收,以及消息长度(结构体大小)*/myPrintfQueue=xQueueCreate(2,sizeof(struct QueuePrint));if(myPrintfQueue==NULL){printf("队列创建失败!\r\n");}xTaskCreate(task1_task,"task1_task",128,NULL,2,NULL); //任务1        xTaskCreate(task2_task,"task2_task",128,NULL,2,NULL);  //任务2 	vTaskStartScheduler();          //开启任务调度
}//任务1函数 发送数据
void task1_task(void *p)
{struct QueuePrint SendData={.Data="adafsf" //随便发个字符串};while(1){SendData.Tick++;xQueueSend(myPrintfQueue,&SendData,0); //队列句柄,发送内容的地址,阻塞时间printf("task1发送数据:%s 次数%d\r\n",SendData.Data,SendData.Tick);vTaskDelay(500);}
}   //任务2函数接收数据 
void task2_task(void *p)
{struct QueuePrint ReceData;BaseType_t xStatus;while(1){xStatus=xQueueReceive(myPrintfQueue,&ReceData,portMAX_DELAY);//portMAX_DELAY:读不到数据就会一直停留在此if(xStatus==pdPASS) //判断接收到数据{taskENTER_CRITICAL();           //进入临界区printf("task2收到数据:%s 次数%d\r\n",ReceData.Data,ReceData.Tick);taskEXIT_CRITICAL();            //退出临界区}}
}

四、实验效果

实验效果如下:
在这里插入图片描述

接上串口,可以看到每500ms,串口打印任务1发送的内容和任务运行次数,以及任务2接收到的内容和任务执行次数,而且收发的数据保持一致。

本节主要是学习和掌握队列操作,以及相关API函数的基本使用。其实在FreeRTOS中队列的重要性也不言而喻,与FreeRTOS任务调度同等重要,因为后面的各种信号量基本都是基于队列的。
完整程序放在gitee仓库上:程序下载。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java编程练习之多重继承

在Java中类不允许多重继承,但使用接口可以实现多重继承,因为一个类可以同时实现多个接口,这样可以将所有需要实现的接口放在implements关键字后,并使用英文逗号隔开,但这可能会在一个类中产生庞大的代码量,…

【C++】1390-请从键盘读入一个四位整数,求这个四位整数各个位的和是多少?

问题:1390-请从键盘读入一个四位整数,求这个四位整数各个位的和是多少? 类型:基础问题 题目描述: 请从键盘读入一个四位整数,求这个四位整数各个位的和是多少? 输入: 一个四位整…

有条件的打破IBGP水平分割----反射规则和联邦+实验举例

背景:在一个AS中的设备运行了BGP协议,那么正常应该都连接了其他的AS,存在EBGP邻居关系;又由于IBGP的水平分割规则,导致从外部学习到的路由传递给本地AS时,需要和本地AS中运行BGP协议都要建立IBGP邻居关系&a…

python中time库的time.time()函数的作用是什么?

python中time库的time.time()函数的作用是什么? 作用:Python time time() 返回当前时间的时间戳(1970纪元后经过的浮点秒数)。 time()方法语法:time.time() #!/usr/bin/python # Write Python 3 code in this onlin…

PostgreSQL入门到实战-第二十八弹

PostgreSQL入门到实战 PostgreSQL中数据分组操作(三)官网地址PostgreSQL概述PostgreSQL中GROUPING SETS命令理论PostgreSQL中GROUPING SETS命令实战更新计划 PostgreSQL中数据分组操作(三) 使用PostgreSQL grouping sets子句在查询中生成多个分组集。 官网地址 声明: 由于操…

C++ UML 类图介绍与设计

1 类图概述 UML(Unified Modeling Language),即统一建模语言,是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。UML从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图…

Unity 通过权重做随机

我们可以通过Random.Range方法结合权重来实现随机选择。具体步骤如下: 首先,创建一个数组,其中包含你要选择的项目,并为每个项目分配一个权重值。 计算所有权重值的总和。 使用Random.Range生成一个介于0和总权重之间的随机数。…

消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测

Eliminating Cross-modal Conflicts in BEV Space for LiDAR-Camera 3D Object Detection 消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测 摘要Introduction本文方法Single-Modal BEV Feature ExtractionSemantic-guided Flow-based AlignmentDissolved…

2024妈妈杯数学建模A 题思路分析-移动通信网络中 PCI 规划问题

# 1 赛题 A 题 移动通信网络中 PCI 规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上,对各覆盖 小区编号进行合理配置,以避免 PCI 冲突、 PCI 混淆以及 PCI 模 3 干扰等 现象。 PCI 规划对于减少物理层的小区间互相干扰(ICI),增…

jvisualVM分析jvm内存使用快照dump

服务发生内存溢出,就需要查看服务器上Java服务的jvm堆内存使用情况,可以使用dump命令生成dump文件,然后下载到本地,然后使用jvisualVM工具打开,即可实现可视化分析。 生成dump文件常用的两种方式: 第一种…

软件测试基础知识点汇总

1、衡量一个优秀软件的维度 质量模型:功能性、性能、兼容性、易用性、可靠性、安全、可维护性、可移植性。 2、软件测试流程 需求评审、计划编写、用例设计、用例执行、缺陷管理、测试报告 3、用例设计编写格式 用例编号、用例标题、项目/模块、优先级、前置条…

赋能未来:AI技术革新中的创业契机

目录 前言 一、行业解决方案 1、行业参考说明 2、操作步骤建议 二、智能产品和服务 1、行业参考说明 2、操作步骤建议 三、教育和培训 1、行业参考说明 2、操作步骤建议 总结 前言 随着人工智能(AI)技术的快速发展,越来越多的创业…