FreeRTOS——消息队列
目录
一、概念及其作用
1.1概念
1.2特点
1.3工作原理
二、相关API
2.1创建队列
2.2任务中写队列
2.3任务中读队列
2.4中断中写队列
2.5中断中读队列
三、实现原理
3.1消息队列控制块
3.2消息队列的创建
3.3消息的发送
3.3.1任务中发送
3.3.2中断中发送
3.4消息的接收
3.4.1任务中接收
3.4.2中断中接收
一、概念及其作用
1.1概念
FreeRTOS中的消息队列是用与多任务间通信的一种机制。本身队列也是一种FIFO(先进先出)的数据共享结构,凭借这个特点,FreeRTOS操作系统可以实现任务解耦、任务间数据传输。
- 任务解耦:任务之间通过队列进行通信,可以减少任务之间的耦合度,提高代码的模块化程度
- 任务间数据传输:作为共享资源,各任务可以通过向队列读、写数据,实现数据共享和同步
队列中的数据通过发送入队,读取时可以决定是否出队(即是否清除)
FreeRTOS中使用消息队列传输数据默认通过数据拷贝,也就是将发送的数据拷贝到队列中(属于值传递),费时但原始数据可以清除或者覆写
uCOS中的消息队列则采用引用传递,传递的是消息指针。这种方式需要保证传递的消息一直是可见且有效的,像局部变量这种生命周期短的就不能作为消息,但它的好处是节省时间!
因此,虽然默认使用值传递,当要发送的数据太大时,可以考虑发送消息缓冲区的指针
1.2特点
- FIFO先入先出
- 尾写入头读出(可变成头写入尾读出)
- “数据中转站”
- “多对多”
- 消息不定长
- 解决无序
1.3工作原理
队列的实质是:RAM的一段内存空间
二、相关API
队列的使用流程: 创建队列、写队列、读队列、删除队列(需要的情况下使用...)
2.1创建队列
掌握动态的即可
#inlcude "FreeRTOS.h"
#include "queue.h"/*创建队列*/
QueueHandle_t xQueueCreat(UBaseType_t uxQueueLength, UBaseType_t uxItemSize)func:dynamically creat queue and return QueueHandle //动态创建队列并返回句柄params: uxQueueLength 队列一次可容纳消息的最大长度uxItemSize 每个消息体大小 字节为单位,未知的可用sizeofreturn: NULL: 创建失败Any other value: 成功并返回句柄matters needing attention:
Queue can be used between task and task or task and isr;
Queues can be created before the Scheduler is started;
2.2任务中写队列
#inlcude "FreeRTOS.h"
#include "queue.h"/*任务中写队列*/
BaseType_t xQueueSend(QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait) //xQueueSendToFront用于头部紧急插入消息func:transmit message to queue in taskparams: xQueue 要发送进消息的队列句柄pvItemToQueue 要发送的消息的地址xTicksToWait 阻塞等待时间return: pdPass 发送成功errQUEUE_FULL 队列已满发送失败matters needing attention: None
2.3任务中读队列
#inlcude "FreeRTOS.h"
#include "queue.h"/*任务中读队列*/
BaseType_t xQueueReceive(QueueHandle_t xQueue,const void *pvBuffer,TickType_t xTicksToWait) func:receive message from queue in taskparams: xQueue 要读取消息的队列句柄pvBuffer 接收消息的缓冲区xTicksToWait 阻塞等待时间return: pdPass 发送成功errQUEUE_FULL 队列已满发送失败matters needing attention: None
2.4中断中写队列
#inlcude "FreeRTOS.h"
#include "queue.h"/*中断中写队列 xQueueSendToFrontFromISR用于头部紧急插入消息*/
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken)
func:transmit message to queue in ISRparams: xQueue 要发送进消息的队列句柄pvItemToQueue 要发送的消息的地址pxHigherPriorityTaskWoken NULL即可return: pdTrue 发送成功errQUEUE_FULL 队列已满发送失败matters needing attention:
调用此函数,会触发上下文切换
启用调度器之前,不能调用此函数
2.5中断中读队列
#inlcude "FreeRTOS.h"
#include "queue.h"/*中断中读队列*/
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue,const void *pvBuffer,BaseType_t *pxHigherPriorityTaskWoken)func:receive message from queue in ISRparams: xQueue 要发送进消息的队列句柄pvBuffer 接收消息的缓冲区pxHigherPriorityTaskWoken NULL即可return: pdPass 发送成功pdFAIL 消息队列为空matters needing attention:
调用此函数,会触发上下文切换
启用调度器之前,不能调用此函数
可以看到:中断中相关的API都没有xTicksToWait,因为本身中断就是为了紧急响应的,快响应快解决!!!
三、实现原理
3.1消息队列控制块
3.2消息队列的创建
xQueueCreat(实际接口xQueueGenericCreat )
xQueueGenericCreat其中参数queueQueue_Type_BASE 属于队列的一种类型,基于队列创建了很多这样的类型,包括互斥锁、计数信号量、二值信号量、递归锁,可以看出:信号量基于队列实现
-
判断队列空间是否为空
-
是则队列大小赋值为0
-
否则计算队列大小=Length*ItemSize
-
-
申请内存空间(QCB+队列大小),找到队列操作空间首地址
-
初始化消息队列api(队列句柄、长度、size、队列操作空间首地址)
-
判断队列空间是否为空,是则把QCB首地址赋值到队列头指针
-
否则把队列操作空间首地址赋值给队列头指针
-
确定队列Length、ItemSize
-
-
队列重置函数api(队列句柄、操作队列的状态 (一般是传进了pdTRUE))
-
进入临界段
-
头指针赋值,未读消息个数为0,写入指针赋值给头指针,读出指针赋值为头指针+(长度-1)*ItemSize,读写锁解锁
-
判断新建队列状态是否为pdFALSE,是则判断等待发送任务列表项是否有任务,是则移除进行上下文切换
-
否则新建队列,初始化发送、接收列表项
-
退出临界段
-
3.3消息的发送
3.3.1任务中发送
xQueueSend——实际接口为xQueueGenericSend(多了一个参数queSend_TO_BACK,有关入队类型的,尾插、头插或覆盖入队)
-
采用了for循环,为了快速处理数据拷贝的工作
-
挂起调度器——不让任务打断
-
锁定队列——不让中断打断
-
队列上锁——把发送和接收锁都赋值为上锁初始值
3.3.2中断中发送
xQueueSendFromISR——实际接口为xQueueGenericSendFromISR
-
关闭中断同时保存中断状态值
-
队列解锁prvUnlockQueue
-
进入临界段
-
获取发送锁的状态值
-
遍历直到发送锁解锁为止
-
解除等待消息任务,进行上下文切换
-
发送锁减1
-
3.4消息的接收
3.4.1任务中接收
xQueueReceive——实际接口为xQueueGenericReceive(多一个出队模式参数 xJustPeeking)
-
pdFAlSE——出队后,删除已读队列项或消息空间
-
pdTRUE——出队后不删除,然后恢复出队地址,让其他任务或中断继续读取
-
判断是否删除已读消息
-
是则更新消息等待读取的记录值,让它减1
-
否 将未读取之前的地址重新赋值给出队指针
-
3.4.2中断中接收
和中断中发送类似,主要是用到了发送锁和接收锁
相关文章:

FreeRTOS——消息队列
目录 一、概念及其作用 1.1概念 1.2特点 1.3工作原理 二、相关API 2.1创建队列 2.2任务中写队列 2.3任务中读队列 2.4中断中写队列 2.5中断中读队列 三、实现原理 3.1消息队列控制块 3.2消息队列的创建 3.3消息的发送 3.3.1任务中发送 3.3.2中断中发送 3.4消息的…...

【题解】—— LeetCode一周小结46
🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 【题解】—— 每日一道题目栏 上接:【题解】—— LeetCode一周小结45 11.切棍子的最小成本 题目链接:1547. 切棍子的最…...

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中,校运会不仅是…...

python里的数据结构
列表(List) 定义和特点: 列表是一种有序的可变序列,可包含不同类型的元素,如整数、字符串、列表等。可以通过索引访问和修改元素,索引从 0 开始。代码示例: my_list [1, 2, apple, [4, 5]] pr…...

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二十一集:制作游戏的金钱系统吉欧Geo和初步制作HUD Canvas的额外内容
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、制作游戏的金钱系统吉欧Geo以及HUD Camera 1.制作金钱系统吉欧2.制作吉欧的脚本Geo Counter逻辑处理3.制作HUD Canvas的吉欧的UI4.在敌人的HealthManager.c…...
底层逻辑之:极大似然方法(Maximum Likelihood Estimation, MLE)
简介: 极大似然方法(Maximum Likelihood Estimation, MLE)是一种用于估计统计模型参数的方法。其核心思想是基于观测数据来寻找最可能产生这些数据的模型参数。 早在1821年,德国数学家高斯(C. F. Gauss)就…...

笔记:Centos Nginx Jdk Mysql OpenOffce KkFile Minio安装部署
远程工具 ToDesk Nginx 解压 tar zxvf nginx-1.20.2.tar.gz进入Nginx 文件夹 cd nginx-1.20.2报错解决 ./configure: error: C compiler cc is not found yum -y install gcc gcc-c autoconf automake make./configure: error: the HTTP rewrite module requires the PC…...

【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...

深入探索Go语言中的sync.Mutex与sync.RWMutex:原理、应用与实践
深入探索Go语言中的sync.Mutex与sync.RWMutex:原理、应用与实践 在并发编程的世界里,Go语言以其独特的并发模型和简洁的语法赢得了广泛的关注。在Go语言的并发控制工具箱中,sync.Mutex和sync.RWMutex是两个至关重要的工具,它们帮助开发者保护共享资源,避免竞态条件,确保…...

15.postgresql--jsonb 数组进行打平,过滤
用jsonb_array_elements函数先展开数组,再用jsonb_each函数遍历元素中的键值对 例如: SELECT * FROM data_table, LATERAL jsonb_array_elements(json_column) WITH ORDINALITY as elem(element, idx) JOIN LATERAL jsonb_each(elem.element) as kv(ke…...

linux下i2c开发与框架源码分析
目录 1 概述 2 I2c子系统框架 3 I2C的使用流程 3.1 在驱动里使用 3.2 在应用层使用 3.3 I2ctool的使用 4 为硬件i2c注册一个适配器 5 i2c子系统源码流程分析 5.1 i2c device与driver绑定过程 5.1.1 Driver的注册与处理 5.1.2 Client device的生成 5.2 I2c的发送与接…...

[ruby on rails] 安装docker
1. docker安装 ubuntu14.04后自带docker安装包,可以直接安装docker.io sudo apt-get updatesudo apt-get install -y docker.io # 安装后启动sudo service docker start最新版本docker 安装docker-ce # 官方源 curl -fsSL https://download.docker.com/linux/ubun…...

I2C学习
详情学习 12. I2C通讯 — [野火]Linux基础与应用开发实战指南——基于LubanCat-RK系列板卡 文档 (embedfire.com) 问题 i2c总线中scl和sda两条线的作用以及区别 在 I2C 总线(Inter-Integrated Circuit)中,SCL 和 SDA 是两条核心信号线&am…...

VUE:基于MVVN的前端js框架
文章目录 vue框架v-show vue框架 注意是 先写函数名,再写function。 handle:function (){}下面是错误的 function:handle(){}3 v-show 本质上等于号后面还是判断条件,所以不能写赋值语句,下面是正确的 下面是错误的 v-show " ge…...

06、Spring AOP
在我们接下来聊Spring AOP之前我们先了解一下设计模式中的代理模式。 一、代理模式 代理模式是23种设计模式中的一种,它属于结构型设计模式。 对于代理模式的理解: 程序中对象A与对象B无法直接交互,如:有人要找某个公司的老总得先打前台登记传达程序中某个功能需要在原基…...

c语言学习26字符串的应用
字符串在stm32串口中的应用 串口控制流水灯 pc通过串口发送字符串命令控制流水灯 open 流水灯打开 close 流水灯关闭 speed 1~9速度控制 if(strcmp((char *)usart1_rec_buff,"open")0) { led_flag 1; } else if(strcmp((char *)usart1_rec_buff,"close&qu…...

法语旅游常用口语-柯桥学外语到蓝天广场泓畅学校
以下是一些实用的法语旅游常用口语,帮助你在法国旅行时能够进行基本的交流: 问候与道别 Bonjour: 用于日常问候。Au revoir: 用于告别。 请求帮助 S’il vous plat: 用于请求帮助,例如在需要寻找某个地点或服务时。 询问信息 Excusez-moi: 用…...

Kafka 生产者优化与数据处理经验
Kafka:分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析:从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析:…...

MySQL 主从复制之多线程复制
一、MySQL 多线程复制的背景 MySQL 的主从复制延迟一直是受开发者最为关注的问题之一,MySQL 从 5.6 版本开始追加了并行复制功能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。…...

Linux2.6内核进程调度队列
文章目录 前言运行队列 runqueue优先级活动队列过期队列活跃队列 VS 过期队列active指针和expired指针O(1)调度算法 前言 在前面学习并认识了进程之后,我们会发出一个疑问:Linux内核是如何调度进程的呢? 接下来我们就以Linux2.6内核为例深入探…...

Infineon(英飞凌) TLE985xQX 芯片电机工作电流、电压AD采样
其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 单片机芯片合集 文章目录 其他系列文章导航 文章目录 前言 一、选取合适的端口 1.通过 OP1、OP2 电流采集运放输入端口进行H桥驱动的电流采集。 2.通过 O_D_VBAT_AD_EN、I_A_VBAT_A…...

Sparrow系列拓展篇:对信号量应用问题的深入讨论
前言 笔者之前已经介绍过了Sparrow信号量的源码,但是对于信号量的使用,并没有讲得非常详细,仅仅讲了同步与互斥的概念。 本章让笔者介绍如何使用Sparrow的信号量,深入探讨一下信号量在同步、计数与互斥中的应用。 使用信号量解…...

图文详解Docker下配置、测试Redis
文章目录 前言实测环境:实验思路: 正文1.准备工作2. 配置、运行 Redis 容器3. 配置测试 总结 前言 配置、测试redis数据库服务器,首先确保正确安装docker,并且已启动运行,具体安装docker方法见笔者前面的博文《OpenEu…...

Python编程艺术:优雅与实用的完美平衡(推导式)
在Python这门优雅的编程语言中,处处体现着"简洁即是美"的设计哲学。今天我们深入探讨Python中那些让代码更优雅、更高效的编程技巧,这些技巧不仅能提升代码的可读性,还能让编程过程充满乐趣。 列表推导式的魔力 Python的列表推导…...

Spring Boot框架Starter组件整理
在Spring Boot框架中,starter是一种预定义的依赖集合,旨在简化Maven或Gradle等构建工具中的依赖管理。每个starter都包含了实现特定功能所需的库和组件,以及相应的配置文件。开发者只需在项目中引入相应的starter依赖,即可快速搭建…...

C/C++基础知识复习(27)
1) 移动语义和拷贝语义的区别 拷贝语义和移动语义是C中对象所有权管理的两种机制,主要在对象初始化、赋值或传参时体现。 拷贝语义 (Copy Semantics) 行为:通过深拷贝或浅拷贝,创建一个新对象,并将原对象的值或资源复制到新对象…...

IEC61850实现方案和测试-2
IEC61850实现方案和测试-1作为介绍实现方案和测试的第二篇文章,后续会继续更新,欢迎关注。 第一篇是:IEC61850实现方案和测试-1-CSDN博客 UCA详细测试用例下载: 链接: https://pan.baidu.com/s/1TTMlYRfzKITgrkWwwtcrDg 提取码:…...

flume-将日志采集到hdfs
看到hdfs大家应该做什么? 是的你应该去把集群打开, cd /export/servers/hadoop/sbin 启动集群 ./start-all.sh 在虚拟机hadoop02和hadoop03上的conf目录下配置相同的日志采集方案,‘ cd /export/servers/flume/conf 切换完成之后&#…...

一文学习开源框架LeakCanary
LeakCanary 简介 LeakCanary 是一个由 Square 开发的开源工具,主要用于检测和诊断 Android 应用中的内存泄漏问题。它通过自动化的方式帮助开发者捕捉和分析可能导致内存泄漏的对象,简化了内存问题的排查过程。 LeakCanary 的功能 自动检测内存泄漏&a…...

jetson orin系列开发版安装cuda的gpu版本的opencv
opencv安装包下载地址: https://github.com/opencv/opencv/扩展库下载地址: https://github.com/opencv/opencv_contrib1. 删除jetpack包中的opencv版本 原先的opencv库安装在目录/usr/lib/aarch64-linux-gnu/下(一般其他的第三方库也都安…...