FreeRTOS进程间通信-消息队列

2023-05-16

消息队列是进程间的一种通信机制,实际项目运用很多。

1、什么是消息队列?

2、消息队列API函数

3、在进程间通信使用消息队列

4、在中断中使用消息队列

1.1、消息队列是什么?

      消息队列是realtime os 内核提供的服务,任务之间或者是中断中可以将一个消息放到队列中进行传递,freertos可以通过内核API获取到队列中的数据,freertos传递了实际数据。消息可以由多个任务压入队列,一个队列也可以被多个任务读取,消息队列的获取遵循fifo原则,freertos支持fifo以及lifo.

对比裸机编程,消息队列有如下特点:

a.裸机下需要自己实现超时等待机制,rtos下不用自己实现,且该机制的数据管理交给rtos;

b.裸机下的全局变量需要防止多任务访问冲突,消息队列自己处理这个问题,无需码农担心这个问题;

c.解决中断server和task之间的消息传递;

1.2消息队列的实现方式

通过图片可对消息队列有个具体认知。

---》该队列可以存放是个数据单元;

---》task1给task2传递数据,task2从队列中获取数据;

---》fifo方式存取;

存取过程会出现两种情况:

a、task1存放数据速度大于task2 速度,会出现队列放满的情况,freertos 中的xQueueSend已经实现超时等待功能,用户可以设置超时等待时间直到超时时间溢出或者是队列有空;

b、队列会满当然也会空,当队列为空,依然可以设置超时等待,直到超时或者是队列有数据;

1.3在中断中实现消息队列

a.中断中无法实现超时等待功能,所以在中断里面往队列里面压数据需要先判断队列是否满,消息队列发送函数xQueueSendFromISR不支持超时设置。

b、队列会满当然也会空,当队列为空,依然可以设置超时等待,直到超时或者是队列有数据;

注意:

a.中断serverfunc需要尽量短,因为进入中断是进入临界区下的代码,是关闭中断的,如果代码太长,会导致其他中断得不到及时响应;

b.中断服务程序中一定要调用专用于中断的消息队列函数,即以FromISR结尾的函数

 

2.消息队列API

(1)    xQueueCreateStatic() 
(2)    vQueueDelete()
(3)    xQueueSend()
(4)    xQueueSendFromISR()
(5)    xQueueSendToBack()
(6)    xQueueSendToBackFromISR()
(7)    xQueueSendToFront()
(8)    xQueueSendToFrontFromISR()
(9)    xQueueReceive()
(10)    xQueueReceiveFromISR()
(11)    uxQueueMessagesWaiting()
(12)    uxQueueMessagesWaitingFromISR()
(13)    uxQueueSpacesAvailable()
(14)    xQueueReset()
(15)    xQueueOverwrite()
(16)    xQueueOverwriteFromISR()
(17)    xQueuePeek()
(18)    xQueuePeekFromISR()
(19)    vQueueAddToRegistry()
(20)    vQueueUnregisterQueue()
(21)    pcQueueGetName()
(22)    xQueueIsQueueFullFromISR()
(23)    xQueueIsQueueEmptyFromISR()

 

2.1主要函数:

 

(1)    xQueueCreate ()

函数xQueueCreate用于创建消息队列。

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

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

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

 

(2)    xQueueSend ()

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

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

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

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

u  返回值,如果消息成功发送返回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方式的存取。

 

(3)    xQueueSendFromISR ()

 

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

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

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

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

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

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

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

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

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

 

(4)    xQueueReceive ()

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

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

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

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

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

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

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

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

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

查看板子原理图,sclk链接的是GPIO5(哈哈,抽烟太多,板子在吃烟灰)

 

示例代码:

使用中断中的消息队列为api为实例:


static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
void mrfc_630_task()
{
unsigned char io_num;
    gpio_config_t io_conf;
      io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
    //bit mask of the pins, use GPIO4 here
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    //set as input mode    
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    //create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));

    //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    //hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);///add intrrupt function 
while(1)
{

  if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }

}


}

 

测试结果如下(获取中断引脚的电平):

GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
GPIO[5] intr, val: 0
I (4843571) Touch pad: Waiting for any pad being touched...
I (4848571) Touch pad: Waiting for any pad being touched...

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS进程间通信-消息队列 的相关文章

  • 使用RabbitMQ实现延时队列

    之前公司是一个类电商公司 会有用户下单后未支付取消订单的场景 解决方案是使用RabbitMQ的死信队列来实现一个延时队列 下单时 将订单丢进消息队列 设置过期时间 订单失效时间 然后到时候检查订单状态 如果未支付则取消订单 1 什么是死信
  • 非阻塞的connect使用方式

    connect 函数的调用涉及到3次握手 默认connect函数为阻塞连接状态 通常connect 会阻塞到三次握手的完成和失败 而这个connect阻塞超时时间会依赖于系统 一般为75s到几分钟时间 一种方式可以通过该系统配置 proc
  • FreeRTOS,串口中断接收中使用xQueueOverwriteFromISR()函数,程序卡死在configASSERT

    原因 UART的中断优先级设置的太高 高于了configMAX SYSCALL INTERRUPT PRIORITY宏定义的安全中断等级 UART的中断等级小于等于宏定义的优先等级即可
  • RocketMQ消费重试问题

    异常现象 监控日志展示如下 2019 10 30 14 31 23 339 INFO ConsumeMessageThread 7 com xxx service mq MQConsumerService 93 消费消息 msgId 0A0
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • RocketMQ 简介

    本文根据阿里云 RocketMQ产品文档整理 地址 https help aliyun com document detail 29532 html userCode qtldtin2 简介 RocketMQ是由阿里捐赠给Apache的一款
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • 秒杀系统中常见问题及解决方案

    秒杀中的常见问题的解决 1 解决超卖的问题 1 Redis预减库存 有一个下单请求过来时预减库存 若减完后的redis库存小于0说明已经卖完 此时直接返回客户端已经卖完 后续使用内存标记 减少Redis访问 若预减库存成功 则异步下单 请求
  • FreeRTOS笔记(二)

    FreeRTOS笔记 二 静态任务 文章目录 FreeRTOS笔记 二 静态任务 一 任务定义 二 任务创建 2 1 定义任务栈 2 2 定义任务函数 2 3 定义任务控制块 2 4 实现任务创建函数 三 实现就绪列表 3 1 定义就绪列表
  • RocketMQ系列之架构浅谈

    RMQ的架构设计 下面我从GitHub上截取了一张RMQ的源码结构图 图中我框框出来的9大模块 基本就构成了整个RMQ的内部结构 上面9大模块的依赖层次主要如下 依赖越强的越处于底层 下面介绍下最上层的4个模块 这4个模块中工具命令行就不讲
  • RocketMQ-高级原理

    本节讲解下当MQ消息消费失败 或者发送不成功时如何处理消息 消息发送不成功一般存在于几种情况 网络原因 服务宕机 或者broker配置 消息发送失败 如果是由于broker配置原因 可以通过报错提示排查原因 无法查到路由信息 一般考虑到ro
  • RocketMQ第四篇 Rocket集群配置

    在实际开发中一般都会使用docker安装rocketMQ docker安装rocketmq如下 docker安装配置rocketmq docker安装rocketmq docker pull foxiswho rocketmq server
  • Springboot中配置activeMQ持久化

    一 activeMQ数据库持久化配置 ActiveMQ持久化的三种方式 我们采用数据库的方式来进行持久化 1 Memory 消息存储 基于内存的消息存储 2 基于日志消息存储方式 KahaDB是ActiveMQ的默认日志存储方式 它提供了容
  • 重试机制的实现(4m,10m,10m,1h,2h,6h,15h)

    项目场景 由于我们现在所做的项目有有很多的外放接口供代理商调用 但是有些接口的响应并不是实时返回的 此时我们就需要使用回调接口的方式 将信息响应给代理商 在这期间可能会出网络不稳定等其他情况 导致回调接口调用失败 所以需要特定的回调重试机制
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • C++ freeRTOS任务,非静态成员函数的无效使用

    哪里有问题 void MyClass task void pvParameter while 1 this gt update void MyClass startTask xTaskCreate this gt task Task 204
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • 敏捷开发:做一个合格的Scrum Master

    图片来源于网络 Scrum Master Beauty and Beast 在Scrum敏捷开发中有三种主要的角色 xff1a Product Owner xff08 产品负责人 xff0c 简称 34 PO 34 xff09 Scrum
  • 嵌入式软件:通过串口进行调试的一些思考和实践

    最近的工作还是改那坨代码 维护这摊东西也快要2年了 xff0c 好几次想重构它 xff0c 顺便整理一下 xff0c 不过我还是缺乏那种毅力 在这段时间里我还加了一些功能模块 xff0c 估计如果以后有新人接手这摊东西 xff0c 会抱怨这
  • 串口调试助手没有显示

    用cubeMX生成工程之后 xff0c 笔者写了下面两句话 xff08 向串口发送一个字符串 xff09 xff1a 但是 xff0c 打开调试工具怎么也接受不到数据 xff0c 魔术棒里面的 芯片型号 xff0c 调试 xff08 J L
  • vscode使用gitee

    vscode使用gitee 首先选择文件夹右键用vscode打开 然后打开vscode的终端 xff1a 在终端输入命令 xff1a xff08 每行命令输入完成之后记得敲回车 xff09 xff1a git init然后敲回车就有 xff
  • 深度揭秘阿里(蚂蚁金服)技术面试流程!附前期准备,学习方向

    上半年公司的项目很闲 xff0c 很多人觉得没意思陆续走了 xff0c 我考虑到自己的发展 xff0c 从6月底开始面 xff0c 面到7月底 xff0c 三十家公司 我从不打没准备的仗 xff0c 我是一个喜欢总结经验的人 xff0c 每
  • Git 中submodule的使用,终于有人说明白了

    背景 面对比较复杂的项目 xff0c 我们有可能会将代码根据功能拆解成不同的子模块 主项目对子模块有依赖关系 xff0c 却又并不关心子模块的内部开发流程细节 这种情况下 xff0c 通常不会把所有源码都放在同一个 Git 仓库中 有一种比
  • git 工具GitEye使用

    二 xff1a 签入 右键commit 可以选择需要签入的 xff0c 要加入注释才能签入 一 xff1a 比较
  • ROS笔记十(基于Python、Kinetic):rviz基础——快速配置并渲染点云和摄像机图像数据

    前言 xff1a rviz xff08 ROS visualization xff09 xff1a 用于机器人 传感器和算法的通用3D可视化系统 rviz能够绘制多种类型的数据流 特别是三维的数据 在ROS中所有类型的数据都被关联到一个参考
  • java面试必看书单

    编程之法 https legacy gitbook com book wizardforcel the art of programming by july details 白话经典算法之七大排序 链接 xff1a https pan ba
  • Java基础 - Integer和int的区别

    一 int和Integer的区别 两者的区别主要体现在以下几个方面 xff1a 1 数据类型不同 xff1a int 是基础数据类型 xff0c 而 Integer 是包装数据类型 xff1b 2 默认值不同 xff1a int 的默认值是
  • Lua + GraphicsMagick安装

    Lua 43 GraphicsMagick安装 图片的实时缩放功能是Nginx调用Lua脚本 xff0c Lua脚本在FastDFS中下载对应的图片保存到本地 xff0c 然后Lua调用GraphicsMagick实现图片的缩放功能 1 安
  • 零基础应该选择学习 C、C++、Java、python、web前端、C#、PHP、Linux选哪个编程语言好呢?

    众多的语言 xff0c 到底哪一门才是适合我呢 xff1f 小白 xff1a 大佬 xff0c 大佬 xff0c 编程语言也太多了 xff0c 到底我应该选择哪一种呢 xff1f 大佬 xff1a 首先呢 xff0c 我们先对常见的编程语言
  • 如何看英文技术文档

    https www jianshu com p af7d39cac6b8
  • 从工具的奴隶到工具的主人

    摘要 xff1a 我们每个人都是工具的奴隶 随着我们的学习 xff0c 我们不断的加深自己对工具的认识 xff0c 从而从它们里面解脱出来 现在我就来说一下我作为各种工具的奴隶 xff0c 以及逐渐摆脱它们的思想控制的历史吧 当我高中毕业进
  • 程序员,这四个学习建议值得收藏

    大家好 xff0c 我是本周的值班编辑 江南一点雨 xff0c 本周将由我为大家排版并送出技术干货 xff0c 大家可以在公众号后台回复 springboot xff0c 获取最新版 Spring Boot2 1 6 视频教程试看 在我看来
  • 底层原理解析

    目录 HashMap底层原理 xff1a ConcurrentHashMap 底层原理 HashMap底层原理 xff1a 1 HashMap概述 xff1a HashMap是一个散列桶 xff08 数组和链表 xff09 xff0c 它存
  • Java ServerSocket & Socket 实现 单组【客户端⇄服务端】双工通信(双向通信)

    Server java 服务器端开启服务 package com example socket service import lombok SneakyThrows import java net ServerSocket import j
  • docker搭建容器过程

    docker 环境创建 配置apt国内镜像源 备份源 span class token function cp span etc apt sources list etc apt sources list backup span class
  • FreeRTOS进程间通信-消息队列

    消息队列是进程间的一种通信机制 xff0c 实际项目运用很多 1 什么是消息队列 xff1f 2 消息队列API函数 3 在进程间通信使用消息队列 4 在中断中使用消息队列 1 1 消息队列是什么 xff1f 消息队列是realtime o