FreeRTOS队列

article/2025/8/27 4:30:27

       在实际的应用中,常常会遇到一个任务或者中断服务需要和另外一个任务进行“沟通交流”,这个“沟通交流”的过程其实就是消息传递的过程。在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式,但是如果在使用操作系统的应用中用全局变量来传递消息就会涉及到“资源管理”的问题。FreeRTOS对此提供了一个叫做“队列”的机制来完成任务与任务、任务与中断之间的消息传递。本章我们就来学习FreeRTOS队列,本章分为如下几部分:

13.1队列简介

13.2队列结构体

13.3队列创建

13.4向队列发送消息

13.5队列上锁和解锁

13.6从队列读取消息

13.7队列操作实验

13.1队列简介队列

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

13.3队列创建

13.3.1函数原型

在使用队列之前必须先创建队列,有两种创建队列的方法,一种是静态的,使用函数xQueueCreateStatic();另一个是动态的,使用函数xQueueCreate()。这两个函数本质上都是宏,真正完成队列创建的函数是xQueueGenericCreate()和xQueueGenericCreateStatic(),这两个函数在文件queue.c中有定义,这四个函数的原型如下。

1、函数xQueueCreate()此函数本质上是一个宏,用来动态创建队列,此宏最终调用的是函数xQueueGenericCreate(),函数原型如下:

QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength,UBaseType_t uxItemSize)

参数:

uxQueueLength:要创建的队列的队列长度,这里是队列的项目数。

uxItemSize:队列中每个项目(消息)的长度,单位为字节

返回值:

其他值:队列创捷成功以后返回的队列句柄!

NULL:队列创建失败。

2、函数xQueueCreateStatic()

此函数也是用于创建队列的,但是使用的静态方法创建队列,队列所需要的内存由用户自行分配,此函数本质上也是一个宏,此宏最终调用的是函数xQueueGenericCreateStatic(),函数原型如下:

QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,UBaseType_t uxItemSize,uint8_t *pucQueueStorageBuffer,StaticQueue_t *pxQueueBuffer)

参数:

uxQueueLength:要创建的队列的队列长度,这里是队列的项目数。

uxItemSize:队列中每个项目(消息)的长度,单位为字节

pucQueueStorage:指向队列项目的存储区,也就是消息的存储区,这个存储区需要用户自行分配。此参数必须指向一个uint8_t类型的数组。这个存储区要大于等于(uxQueueLength * uxItemsSize)字节。

pxQueueBuffer:此参数指向一个StaticQueue_t类型的变量,用来保存队列结构体。

返回值:

其他值:队列创捷成功以后的队列句柄!

NULL:队列创建失败。

3、函数xQueueGenericCreate()函数

xQueueGenericCreate()用于动态创建队列,创建队列过程中需要的内存均通过FreeRTOS中的动态内存管理函数pvPortMalloc()分配,

函数原型如下:QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_tuxItemSize, const uint8_t ucQueueType )

参数:

uxQueueLength:要创建的队列的队列长度,这里是队列的项目数。

uxItemSize:队列中每个项目(消息)的长度,单位为字节。

ucQueueType:队列类型,由于FreeRTOS中的信号量等也是通过队列来实现的,创建信号量的函数最终也是使用此函数的,因此在创建的时候需要指定此队列的用途,也就是队列类型,一共有六种类型:

queueQUEUE_TYPE_BASE普通的消息队列

queueQUEUE_TYPE_SET队列集

queueQUEUE_TYPE_MUTEX互斥信号量

queueQUEUE_TYPE_COUNTING_SEMAPHORE计数型信号量

queueQUEUE_TYPE_BINARY_SEMAPHORE二值信号量

queueQUEUE_TYPE_RECURSIVE_MUTEX递归互斥信号量函数

xQueueCreate()创建队列的时候此参数默认选择的就是queueQUEUE_TYPE_BASE。

返回值:

其他值:队列创捷成功以后的队列句柄!

NULL:队列创建失败。

4、函数xQueueGenericCreateStatic()

此函数用于动态创建队列,创建队列过程中需要的内存需要由用户自行分配好,函数原型如下:

QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType )

参数:

uxQueueLength:要创建的队列的队列长度,这里是队列的项目数。

uxItemSize:队列中每个项目(消息)的长度,单位为字节

pucQueueStorage:指向队列项目的存储区,也就是消息的存储区,这个存储区需要用户自行分配。此参数必须指向一个uint8_t类型的数组。这个存储区要大于等于(uxQueueLength * uxItemsSize)字节。

pxStaticQueue:此参数指向一个StaticQueue_t类型的变量,用来保存队列结构体。

ucQueueType:队列类型。

返回值:

其他值:队列创捷成功以后队列句柄!

NULL:队列创建失败。

13.4向队列发送消息

 

13.6从队列读取消息

/按键消息队列的数量
#define KEYMSG_Q_NUM 1 //按键消息队列的数量 (1)
#define MESSAGE_Q_NUM 4 //发送数据的消息队列的数量(2)
QueueHandle_t Key_Queue; //按键值消息队列句柄
QueueHandle_t Message_Queue;//信息队列句柄
// (1)、队列Key_Queue用来传递按键值的,也就是一个u8变量,所以队列长度为1就行了。并且消息长度为1个字节。
//(2)、队列Message_Queue用来传递串口接收到的数据,队列长度设置为4,每个消息的长度为USART_REC_LEN(在usart.h中有定义)。

 

 

//创建消息
Key_QueueKey_Queue=xQueueCreate(KEYMSG_Q_NUM,sizeof(u8)); (1)//创建消息Message_Queue,队列项长度是串口接收缓冲区长度
Message_Queue=xQueueCreate(MESSAGE_Q_NUM,USART_REC_LEN);(2)

 

//task1任务函数
void task1_task(void *pvParameters)
{
u8 key,i=0;
BaseType_t err;
while(1)
{
key=KEY_Scan(0); //扫描按键 
if((Key_Queue!=0)&&(key)) //消息队列Key_Queue创建成功,并且按键被按下{ 
err=xQueueSend(Key_Queue,&key,10);(3)
if(err==errQUEUE_FULL) //发送按键值 
{printf("队列Key_Queue已满,数据发送失败!\r\n");} 
}i++; 
if(i%10==0) 
check_msg_queue();//检Message_Queue队列的容量(4)if(i==50){i=0; LED0=!LED0; } 
vTaskDelay(10); //延时10ms,也就是10个时钟节拍
}
}

 


http://chatgpt.dhexx.cn/article/qtajTOb8.shtml

相关文章

FreeRTOS任务状态

1. 任务状态介绍 FreeRTOS中的任务状态,可以简单的分为运行态(running)和非运行态(not running)。 但是对于非运行态我们还可以继续细分: 阻塞状态(Blocked)暂停(挂起…

FreeRTOS延时

1、相对延时函数 将当前任务添加到阻塞列表pxDelayedTaskList,任务进入阻塞态。 vTaskDelay → prvAddCurrentTaskToDelayedList → vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) )。任务的阻塞时间更新到状态列表项xStateListItem x…

FreeRTOS多任务管理

文章目录 1、任务1.1 任务简介1.2 任务调度1.3 任务的状态 (就绪态 / 运行态 / 阻塞态 / 挂起态)1.4 空闲任务 2、动态创建两个任务2.1 定义动态内存空间的堆2.2 定义任务函数2.3 定义 任务控制块 指针2.4 动态创建任务 xTaskCreate()2.5 启动任务 vTaskStartScheduler() 3、常…

FreeRTOS 移植

源码 FreeRTOS源码 选择 FreeRTOS 的最新版本 V9.0.0(2016 年)比较稳定 1)解压后的文件 提取的文件, FreeRTOS—>Source->portable目录下的MemMang,RVDS MemMang 存放内存相关的源文件,heap_1.c,heap_2.c,he…

初识FreeRTos

初识FreeRTos Preface一、FreeRTos简介二、 为什么选择FreeRTos三、FreeRTos资料和源码的下载四、介绍我自己的开发环境4.1FreeRTos4.2AlienTek Summary Preface 距离我上一次写博客已经差不多有5个月了,最近想给自己挖个新坑,讲一讲关于FreeRTos 相关的…

FreeRTOS移植

1. 前言 本文是基于FreeRTOSv9.0.0版本的实时系统,移植到STM32F103芯片平台上。移植环境使用的是MDK5.32版本,我在移植之前就已经构建好了一个裸机工程源码了,而且已经确保了这份裸机代码是没有问题的。开始移植之前我强烈建议一定要确认自己…

FreeRTOS快速入门-初探FreeRTOS

首发,公众号【一起学嵌入式】 对于 RTOS 入门系列文章,已经更新完一款(RT-Thread): 助你快速入门 RT-Thread 这个系列的文章结合 RT-Thread,介绍过 RTOS 相关的核心知识。 接下来,开始另外一…

FreeRTOS系列|FreeRTOS简介

1. RTOS简介 RTOS全称为 Real Time Operation System,即实时操作系统。RTOS强调的是实时性,又分为硬实时和软实时。硬实时要求在规定的时间内必须完成操作,不允许超时;而软实时里对处理过程超时的要求则没有很严格。RTOS的核心就…

freertos任务基础知识(freertos篇)

多任务 对于单任务系统就是常说裸机大while循环,有的时候也需要加一些中断服务函数完成一些处理,相比于多任务而言上面的单任务系统也叫做前后台系统,即(中断服务函数叫前台程序,大while叫后台程序) 前后台…

FreeRTOS学习,适用于FreeRTOS初学者,FreeRTOS整体知识框架

目录 一、为什么要学习FreeRTOS 二、前言------从0到1认识FreeRTOS 1、逻辑系统与多任务系统 1.1、裸机系统:裸机系统通常分成轮询系统和前后台系统 1.2、多任务系统 2、数据结构-列表与列表项 三、任务 3.1基本属性 3.1.1任务栈 3.1.2任务控制块 3.1.3任…

一、初识FreeRTOS之FreeRTOS简介

目录 一、什么是FreeRTOS? 二、为什么选择FreeRTOS? 三、FreeRTOS的特点 四、FreeRTOS资料与源码下载 五、FreeRTOS源码文件介绍 一、什么是FreeRTOS? Free即免费的,RTOS的全称是Real time operating system,中文就是实时操作…

Docker技术入门与实战-第3版.pdf OCR 高清 可复制

Docker技术入门与实战-第3版.pdf OCR 高清 可复制 Docker技术入门与实战-第3版.pdf OCR 高清 可复制简介预览下载地址 Docker技术入门与实战-第3版.pdf OCR 高清 可复制 简介 本书从Docker基本原理开始,深入浅出地讲解Docker的构建与操作,内容系统全面…

从docker到kubernetes(k8s)入门与实战--docker教程

安装docker 装个依赖 yum -y install gcc gcc-c 卸载旧版本 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 安装依…

Docker 入门到实战教程(二)安装Docker

一.卸载旧版本 较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。 $ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate…

Docker入门及进阶教程

阅读声明: 该教程笔记来源于dockers——菜鸟教程 一、Docker介绍 1. Docker教程 Docker是一个开源的容器引擎,基于Go语言并遵从Apache2.0协议开源。 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植的容器,然后发…

Docker 实战

目录 一、常用操作 1、镜像创建 2、镜像查询 3、镜像删除 4、镜像运行 5、查询容器进程 6、查询容器执行日志 7、删除容器 8、进入容器 二、导入和导出 1、save 和 load 2、export 和 import 3、区别 三、案例 1、检查是否安装依赖 2、安装依赖 3、docker打包镜…

Docker 实战教程之从入门到提高 (四)

本系列的前三篇文章,我们学习了如何在 Ubuntu 操作系统安装 Docker,并且通过实战练习,了解了 Docker 和宿主机操作系统文件目录互相隔离的实现原理,以及 Docker Volume 的工作原理。通过动手对 Nginx Docker 镜像进行修改&#xf…

Docker快速入门实战

为什么使用容器? 1、上线流程繁琐 2、资源利用率低 3、扩容/缩容不及时 4、服务器环境臃肿 5、环境不一致性 容器VS虚拟机 VM VS Container Docker 是什么 1、使用最广泛的开源容器引擎 2、一种操作系统级的虚拟化技术 3 、依赖于Linux内核特性&#xff1…

Docker教程(Docker实战)

Docker快速入门教程 **欢迎关注公众号【程猿薇茑】** 【仅需一次订阅,作者所有专栏都能看】 推荐【Kafka】https://bigbird.blog.csdn.net/article/details/108770504 推荐【rabbitmq】https://bigbird.blog.csdn.net/article/details/81436980 推荐【Flink】https://blog.csdn…

Docker最全教程——从理论到实战(一)

容器是应用走向云端之后必然的发展趋势,因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。 本篇教程持续编写了2个星期左右,只是为了大家更好地了解、理解和消化这个技术,能够搭上这波车。 你可以关注我们的公众号“magicco…