FreeRTOS(消息队列)

news2025/2/9 3:48:13

 资料来源于硬件家园:资料汇总 - FreeRTOS实时操作系统课程(多任务管理)

目录

一、消息队列的基本概念

1、消息队列的基本概念

2、消息队列的通信机制

3、FreeRTOS中消息队列特性

4、消息队列应用场景

二、消息队列常用API

1、使用消息队列的典型流程

三、消息队列创建与删除

1、消息队列控制块(句柄)

2、队列创建

3、队列删除

四、任务与中断中消息队列发送与接收

1、任务中消息队列发送

2、中断中消息队列发送

3、任务中消息队列接收


一、消息队列的基本概念

1、消息队列的基本概念

消息队列简称队列,是一种常用于任务间通信的数据结构。消息队列可以在任务与任务间、中断与任务间传递消息,实现任务接收来自其它任务或中断的不固定长度的消息。 

相比于裸机的全局数组,使用消息队列有如下优势

①消息队列具有超时机制,可以让 FreeRTOS 内核有效地管理任务

② 使用消息队列可以防止多任务的访问冲突

③ 使用消息队列可以有效地解决中断服务程序与任务之间消息传递的问题,使用全局数组的话,任务得不断去监测标志位以获取数据

④消息队列具有FIFO与LIFO储存机制,方便处理数据

2、消息队列的通信机制

消息队列是一种异步的通信方式。任务能够从队列中读取消息,当队列中的消息为空时,读取消息的任务将被阻塞。用户可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过指定的阻塞时间,即使队列中没有有效数据,任务也会自动从阻塞态转为就绪态。通过消息队列服务,任务或中断服务可以将一条或多条消息放入消息队列中。同样,一个或多个任务可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常是将先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入消息队列的消息,即先进先出原则(FIFO),FreeRTOS的队列也支持后进先出原则(LIFO)。

3、FreeRTOS中消息队列特性

①消息支持先进先出方式排队,支持异步读写工作方式

②读写队列均支持超时机制

③消息支持后进先出方式排队,向队首发送消息(LIFO)

④可以允许不同长度(不超过队列节点最大值)的任意类型消息

⑤一个任务能够从任意一个消息队列接收和发送消息

⑥多个任务能够从同一个消息队列接收和发送消息

⑦当队列使用结束后,可以通过删除队列函数进行删除

4、消息队列应用场景

消息队列可用于发送不定长消息的场合。队列是FreeRTOS 主要的任务间通信方式,可以在任务与任务间、中断和任务间传送信息,发送到队列的消息是通过复制方式实现的,这意味着队列存储的数据是原始数据,而不是原始数据的引用。

二、消息队列常用API

1、使用消息队列的典型流程

①创建消息队列 :xQueueCreate() 

②发送消息队列 :xQueueSend() 与 xQueueSendFromISR()

③读取消息队列 :xQueueReceive()

④删除消息队列:vQueueDelete()

三、消息队列创建与删除

1、消息队列控制块(句柄)

2、队列创建

函数原型:

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, //队列长度消息个数 

                                UBaseType_t uxItemSize ); //类目大小,即消息大小,单位字节

函数描述:函数 xQueueCreate 用于创建消息队列

①第 1 个参数是消息队列支持的消息个数

②第 2 个参数是每个消息的大小,单位字节

③返回值,如果创建成功会返回消息队列的句柄,如果由于 FreeRTOSConfig.h 文件中 heap 大小不足,无法为此消息队列提供所需的空间会返回 NULL

应用:

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
osThreadId KEY1Handle;

//定义队列变量
static QueueHandle_t xQueue=NULL;
static QueueHandle_t xQueue1=NULL;

/* USER CODE END Variables */
  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  xQueue=xQueueCreate(1,4);
  if(xQueue==NULL)
	  HAL_UART_Transmit(&huart2,(uint8_t*)"Create xQueue error... \r\n", 27, HAL_MAX_DELAY);
  else
	  HAL_UART_Transmit(&huart2,(uint8_t*)"Create xQueue success... \r\n", 29, HAL_MAX_DELAY);

  xQueue1=xQueueCreate(2,16);
  if(xQueue1==NULL)
	  HAL_UART_Transmit(&huart2,(uint8_t*)"Create xQueue1 error... \r\n", 28, HAL_MAX_DELAY);
  else
	  HAL_UART_Transmit(&huart2,(uint8_t*)"Create xQueue1 success... \r\n", 30, HAL_MAX_DELAY);
  /* USER CODE END RTOS_QUEUES */

3、队列删除

函数原型:void vQueueDelete( QueueHandle_t xQueue); //队列句柄 

函数描述:

①函数 vQueueDelete 用于删除消息队列

②第 1 个参数是需要删除的消息队列句柄

注意:消息队列删除后,系统会清空此队列的全部消息,且不能再次使用此队列。  

四、任务与中断中消息队列发送与接收

1、任务中消息队列发送

函数原型:BaseType_t xQueueSend( QueueHandle_t xQueue, /* 消息队列句柄 */ 

                    const void * pvItemToQueue, /* 要传递数据地址 */ 

                    TickType_t xTicksToWait /* 等待消息队列有空间的最大等待时间 */ );

函数描述:函数 xQueueSend 用于任务中消息发送。 

① 第 1 个参数是消息队列句柄

② 第 2 个参数要传递数据地址,每次发送都是将消息队列创建函数 xQueueCreate 所指定的单个消息大 小复制到消息队列空间中

③ 第 3 个参数是当消息队列已经满时,等待消息队列有空间时的最大等待时间,单位系统时钟节拍

④ 返回值,如果消息成功发送返回 pdTRUE,否则返回 errQUEUE_FULL

使用这个函数要注意以下问题:

1. FreeRTOS 的消息传递是数据的复制,而不是传递的数据地址。

2. 此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的是xQueueSendFromISR。

3. 如果消息队列已经满且第三个参数为 0,那么此函数会立即返回。

4. 如果用户将 FreeRTOSConfig.h 文件中的宏定义 INCLUDE_vTaskSuspend 配置为 1 且第三个参数配置为 portMAX_DELAY,那么此发送函数会永久等待直到消息队列有空间可以使用。

5. 消息队列还有两个函数 xQueueSendToBack 和 xQueueSendToFront,函数 xQueueSendToBack实现的是 FIFO 方式的存取,函数 xQueueSendToFront 实现的是 LIFO 方式的读写。我们这里说的函数 xQueueSend 等效于 xQueueSendToBack,即实现的是 FIFO 方式的存取。

2、中断中消息队列发送

函数原型:BaseType_t xQueueSendFromISR ( QueueHandle_t xQueue, /* 消息队列句柄 */ 

           const void *pvItemToQueue, /* 要传递数据地址 */ 

           BaseType_t *pxHigherPriorityTaskWoken /* 高优先级任务是否被唤醒的状态保存 */ );

函数描述:函数 xQueueSendFromISR 用于中断服务程序中消息发送。 

① 第 1 个参数是消息队列句柄。 

② 第 2 个参数要传递数据地址,每次发送都是将消息队列创建函数 xQueueCreate 所指定的单个消息大 小复制到消息队列空间中。

③ 第 3 个参数用于保存是否有高优先级任务准备就绪。如果函数执行完毕后,此参数的数值是 pdTRUE,说明有高优先级任务要执行,否则没有。

④ 返回值,如果消息成功发送返回 pdTRUE,否则返回 errQUEUE_FULL。

使用这个函数要注意以下问题:

1. FreeRTOS 的消息传递是数据的复制,而不是传递的数据地址。正因为这个原因,用户在创建消息队列时单个消息大小不可太大,因为一定程度上面会增加中断服务程序的执行时间。

2. 此函数是用于中断服务程序中调用的,故不可以在任务代码中调用此函数,任务代码中使用的是xQueueSend。

3. 消息队列还有两个函数 xQueueSendToBackFromISR 和 xQueueSendToFrontFromISR,函数xQueueSendToBackFromISR 实现的是 FIFO 方式的存取,函数 xQueueSendToFrontFromISR 实现的是 LIFO 方式的读写。我们这里说的函数 xQueueSendFromISR 等效于xQueueSendToBackFromISR,即实现的是 FIFO 方式的存取。

3、任务中消息队列接收

函数原型:BaseType_t xQueueReceive( QueueHandle_t xQueue, /* 消息队列句柄 */ 

                   void *pvBuffer, /* 接收消息队列数据的缓冲地址 */ 

                   TickType_t xTicksToWait /* 等待消息队列有数据的最大等待时间 */ );

函数描述:函数 xQueueReceive 用于接收消息队列中的数据。 

① 第 1 个参数是消息队列句柄。 

② 第 2 个参数是从消息队列中复制出数据后所储存的缓冲地址,缓冲区空间要大于等于消息队列创建函数 xQueueCreate 所指定的单个消息大小,否则取出的数据无法全部存储到缓冲区,从而造成内存溢出。

③ 第 3 个参数是消息队列为空时,等待消息队列有数据的最大等待时间,单位系统时钟节拍。 

④ 返回值,如果接到到消息返回 pdTRUE,否则返回 pdFALSE。

使用这个函数要注意以下问题:

1. 此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序使用的是xQueueReceiveFromISR。

2. 如果消息队列为空且第三个参数为 0,那么此函数会立即返回。

3. 如果用户将 FreeRTOSConfig.h 文件中的宏定义 INCLUDE_vTaskSuspend 配置为 1 且第三个参数配置为 portMAX_DELAY,那么此函数会永久等待直到消息队列有数据。

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

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

相关文章

烘焙光照贴图,模型小部分发黑

1.首先确定创建了光照贴图UV,其次确定不是溢色,这个最简单,所有模型材质设置为双面就可以,URP材质球的话这里就是设置双面 在scence界面Texel Validity模式里查看溢色,红色表示有溢色,绿色表示正常 2. 光照…

异常(中)创建自定义异常,throw,throws关键字抛出异常

文章目录 前言一、创建自定义异常二、在方法中抛出异常 1.使用throw关键字抛出异常2.使用throws关键字抛出异常总结 前言 该文介绍了Java的异常的创建自定义异常,让我们可以自己创建出一个异常,应对Java API中没有的基础的异常报错。throw关键字抛出异常…

【服务平台】Rancher运行和管理Docker和Kubernetes,提供管理生产中的容器所需的整个软件堆栈

Rancher是一个开源软件平台,使组织能够在生产中运行和管理Docker和Kubernetes。使用Rancher,组织不再需要使用一套独特的开源技术从头开始构建容器服务平台。Rancher提供了管理生产中的容器所需的整个软件堆栈。  完整软件堆栈 Rancher是供采用容器的团…

7款轻量级平面图设计软件推荐

平面图设计的痕迹体现在日常生活的方方面面,如路边传单、杂志、产品包装袋或手机开屏海报等,平面设计软件层出不穷。Photoshop是大多数平面图设计初学者的入门软件,但随着设计师需求的不断提高,平面图设计软件Photoshop逐渐显示出…

Ajax 笔记(四)—— Ajax 进阶

笔记目录 4. Ajax 进阶4.1 同步代码和异步代码4.2 回调函数地狱4.2.1 解决方法一:Promise 链式调用4.2.2 解决方法二:async 函数和 await 4.3 Promise.all 静态方法4.4 事件循环4.4.1 事件循环4.4.2 宏任务与微任务 4.5 案例4.5.1 案例一-商品分类4.5.2 …

“反AI斗士”马斯克宣布成立xAI :目标是了解宇宙真实本质

北京时间7月13日凌晨,马斯克在Twitter上宣布:“xAI正式成立,去了解现实。”马斯克表示,推出xAI的原因是想要“了解宇宙的真实本质”。Ghat GPT横空出世已有半年,国内外“百模大战”愈演愈烈,AI大模型的现状…

【golang】数组和切片底层原理

数组类型的值(以下简称数组)的长度是固定的,而切片类型的值(以下简称切片)是可变长的。 数组的长度在声明它的时候就必须给定,并且之后不会再改变。可以说,数组的长度是其类型的一部分。比如&a…

jQuery编程学习3(jQuery 其他方法: jQuery 拷贝对象、 jQuery 多库共存、jQuery 插件)

目录 jQuery 其他方法 1. jQuery 拷贝对象 $.extend()方法 2. jQuery 多库共存 问题概述: 客观需求: jQuery 解决方案:(两种方式) 3. jQuery 插件 jQuery 插件常用的网站: jQuery 插件使用步骤&…

Python-组合数据类型

今天要介绍的是Python的组合数据类型 整理不易,希望得到大家的支持,欢迎各位读者评论点赞收藏 感谢! 目录 知识点知识导图1、组合数据类型的基本概念1.1 组合数据类型1.2 集合类型概述1.3 序列类型概述1.4 映射类型概述 2、列表类型2.1 列表的…

用python来爬取某鱼的商品信息(1/2)

目录 前言 第一大难题——找到网站入口 曲线救国 模拟搜索 第二大难题——登录 提一嘴 登录cookie获取 第一种 第二种 第四大难题——无法使用导出的cookie 原因 解决办法 最后 出现小问题 总结 前言 本章讲理论,后面一节讲代码 拿来练练手的&#xff…

【装个系统】教你安装全新Windows 11 全程展示,精彩无限

跟我一起,穿越时间! Windows 11是微软最新的操作系统,相信已经没有人不知道了,但是很多人还不知道如何安装Windows 11,甚至不知道如何下载微软原版的安装文件, 别急,如果你没有安装文件&#…

纯C#使用Visionpro工具2 操作斑点工具

结果图 通过斑点工具中非圆性找取圆特征 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.For…

7年经验之谈 —— 软件测试工程师,如何工资过万?

对于测试工程师这个岗位而言,月薪过万并不是一件难事,笔者毕业时的第一份工作便拿到了7K的薪资,如今入职两年,薪资也堪堪过了万元大关。 我周边有不少想要入行这一行业的小伙伴都对我目前的工作和生活状态好奇,在此写一…

系列六、Redis中的五大数据类型及相关操作

一、五大数据类型 String类型、List类型、Set类型、ZSet类型、hash类型。 二、String类型 2.1、内存储存模型 2.2、常用操作命令 三、List类型 3.1、概述 list列表,相当于Java中的list集合。特点:元素有序 且 可以重复。 3.2、内存存储模型 3.3、常用…

Arcgis中POI找到建筑面内距离最近的标准地址通过模型构建器来实现

背景 之前写过一篇文章 Arcgis通过矢量建筑面找到POI对应的标准地址 这里面的大致思路跟本篇文章是类似的,不过上一篇文章有部分有瑕疵,就是在POI去找建筑面内的标准地址时,找到的虽然是建筑面内的,但是不一定是距离最近的&#…

Elasticsearch-查询

一、查询和过滤 1.1 相关性分数 :_score 默认情况下,Elasticsearch 按相关性得分对匹配的搜索结果进行排序,相关性得分衡量每个文档与查询的匹配程度。 相关性分数是一个正浮点数,在搜索的数据字段中返回。_score越高&#xff0…

KAFKA第二课之生产者(面试重点)

生产者学习 1.1 生产者消息发送流程 在消息发送的过程中,涉及到了两个线程——main线程和Sender线程。在main线程中创建了一个双端队列RecordAccumulator。main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到K…

vant van-tabs van-pull-refresh van-list 标签栏+上拉加载+下拉刷新

<template><div class"huibj"><div class"listtab"><!--顶部导航--><div class"topdh"><topnav topname"余额明细"></topnav></div><!--Tab 标签--><van-tabs v-model"…

126、高频Redis面试题:如何保证Redis和数据库数据一致性

高频Redis面试题:如何保证Redis和数据库数据一致性 缓存用法如何更新缓存先更新缓存&#xff0c;再更新数据库先更新数据库&#xff0c;再更新缓存先删除缓存&#xff0c;再更新数据库延时双删&#xff08;删除缓存&#xff0c;更新数据库&#xff0c;再延时删除缓存&#xff0…

Linux 内存管理新特性 - Memory folios 解读 | 龙蜥技术

本文内容基于 Linux 5.16&#xff0c;folio 基础部分开始合入。截止到目前 Linux 6.5&#xff0c;folio 已经有很大进展&#xff0c;会在后续文章中介绍。作者&#xff1a;徐宇。 01 folio [ˈfoʊlioʊ] 是什么 引用 LWN: Memory folios &#xff1a;https://lwn.net/Articl…