消息队列缓存,以蓝牙消息服务为例

news2025/6/13 22:10:58

前言

消息队列缓存,支持阻塞、非阻塞模式;支持协议、非协议模式

可自定义消息结构体数据内容

使用者只需设置一些宏定义、调用相应接口即可

这里我用蓝牙消息服务举例

有纰漏请指出,转载请说明。

学习交流请发邮件 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 4

										 
typedef 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 MsgBlock
	if (queue->size == 0)
	{
		return eQueueEmpty;
	}
	else if (queue->size == QueueMaxSize)
	{
		return eQueueFull;
	}
	else
	{
		return eQueueNormal;
	}	
#else
	if (queue->msgCnt == 0)
	{
		return eQueueEmpty;
	}
	else if ( queue->msgCnt > 0)
	{
		return eQueueNormal;
	}
#endif		
}

void MsgEnQueue(MSG_ATTR_S *queue, MSG_S *data)
{
#if MsgBlock
	if (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));
}

一个图图

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

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

相关文章

4D视频数据集

RealGraph: A Multiview Dataset for 4D Real-world Context Graph Generation RealGraph是一个全新的4D视频数据集&#xff0c;旨在支持“Context Graph Generation (CGG)”任务。CGG任务的目标是从动态场景的校准多视图视频中恢复出物体的语义信息&#xff0c;包括坐标、轨迹…

Idea报错 java: 程序包org.springframework.boot不存在 解决方法

发现我的是因为更改了maven的主路径和本地仓库路径&#xff0c;但是新建了一个工程后&#xff0c;设置就恢复默认了。需要重新设置正确路径。 应用后会重新下载依赖项 之后虽然还会报错&#xff0c;但是已经不影响项目运行&#xff0c;配置成功

高速数字化仪和AWG在车辆总线(CAN/LIN/PSI5)测试中的应用(一)

引言 模块化仪器比传统仪器的尺寸大大减小&#xff0c;适合安装在电路卡上&#xff0c;同时也可以将多个卡插入具有通用计算机接口、电源和互连的框架中。模块化仪器框架包括使用标准PCIe接口的计算机、PXI测试框架或基于LXI的盒子&#xff0c;工程师通常会使用多个卡并将其配…

基于Docker-compose搭建LNMP

1、配置nginx 创建nginx目录上传所需压缩包将wordress解压到指定路径下 配置Dockerfile文本文件 vim DockerfileFROM centos:7 MAINTAINER this is nginx image <zgc> RUN yum -y install pcre-devel zlib-devel gcc gcc-c make RUN useradd -M -s /sbin/nologin nginx…

【RcoketMQ】RcoketMQ 5.0新特性(二)- Pop消费模式

Pop模式消费和消息粒度负载均衡 在RocketMQ 5.0之前&#xff0c;消费有两种方式可以从Broker获取消息&#xff0c;分别为Pull模式和Push模式。 Pull模式&#xff1a;消费需要不断的从阻塞队列中获取数据&#xff0c;如果没有数据就等待&#xff0c;这个阻塞队列中的数据由消息…

springBoot 自动配置机制

springBoot 自动配置机制 自动配置的tomcat、springmvc等默认包扫描规则自定义扫描路径配置默认值按需加载自动配置总结 自动配置的tomcat、springmvc等 导入场景&#xff0c;容器中就会自动配置好这个场景的核心组件 以前&#xff1a;dispatcherservlet、viewresolver、chara…

MyCat分片规则

MyCat是一个开源的数据库中间件&#xff0c;它可以实现对MySQL数据库进行分片和负载均衡。在分片规则方面&#xff0c;MyCat支持以下几种常见的分片方式&#xff1a; 范围分片 根据指定的字段及其配置的范围与数据节点的对应情况&#xff0c; 来决定该数据属于哪一个分片。 …

LeetCode【438】找到字符串中所有字母异位词

题目&#xff1a; 注意&#xff1a;下面代码勉强通过&#xff0c;每次都对窗口内字符排序。然后比较字符串。 代码&#xff1a; public List<Integer> findAnagrams(String s, String p) {int start 0, end p.length() - 1;List<Integer> result new ArrayL…

Leetcode——统计数组中的元素练习

错误的集合 此题没做出来 class Solution { public:vector<int> findErrorNums(vector<int>& nums) {vector<int> errorNums(2);int n nums.size();sort(nums.begin(), nums.end());// 记录上一个元素int prev 0;for (int i 0; i < n; i) {int cu…

什么是指标体系,怎么搭建一套完整的指标体系?(附PDF素材)

什么是指标体系&#xff0c;怎么搭建一套完整的指标体系&#xff1f;数字化转型过程中&#xff0c;这个问题一直困扰着数据分析师。主要体现在&#xff1a; 各部门根据业务需求&#xff0c;都有一部分量化指标&#xff0c;但不够全面&#xff0c;对企业整体数据分析应用能力提…

4.0 Beta2版本编译RK3588错误问题解决

最近有小伙伴在问4.0 Beta2版本编译RK3588&#xff08;也就是dayu210&#xff09;时&#xff0c;会有各种莫名奇妙的报错 &#xff08;1&#xff09;subsystem name config incorrect in ....... 这个原因是OH代码加入了编译检查&#xff0c;临时措施是把需要编译检查的文件放…

提升自媒体影音创作效率,这 10 款 AI 工具打工人必备!

随着AI工具的不断涌现&#xff0c;自媒体影音创作的效率也得到了提升&#xff0c;本次为大家介绍10款AI影音工具&#xff0c;为你的自媒体创作助力&#xff01; 还是先上一张脑图&#xff1a; 自媒体必备AI工具 1. Runway AI视频编辑工具&#xff0c;支持文字转视频 目前最…

Elasticsearch:使用 Langchain 和 OpenAI 进行问答

这款交互式 jupyter notebook 使用 Langchain 将虚构的工作场所文档拆分为段落 (chunks)&#xff0c;并使用 OpenAI 将这些段落转换为嵌入并将其存储到 Elasticsearch 中。然后&#xff0c;当我们提出问题时&#xff0c;我们从向量存储中检索相关段落&#xff0c;并使用 langch…

UnityShaderLab —— 简单的流光shader

原理&#xff1a; 就是在原先的模型表面叠加一层可以流动的图片&#xff0c; 算法代码&#xff1a; float2 tex; tex float2(i.uv.x - _Time.x * _Speed,i.uv.y); fixed4 col0 tex2D(_Tex, tex)* _Strenth; fixed4 col1 tex2D(_MainTex, i.uv); return col0 col1; 这里…

ADS版图中连接提示线设置

ADS版图连接提示线设置 简述solve 简述 在ADS版中连接提示线设置&#xff0c;如下图1所示&#xff0c;有点类似于AD中“金线”&#xff0c;提示同一网络的焊盘&#xff0c;但在ads中&#xff0c;是产生了同一层的wire&#xff0c;证据如图2所示。如果没有设置的话&#xff0c;…

【Java学习之道】字符串处理工具类

引言 在Java中&#xff0c;我们常常需要处理字符串&#xff0c;比如读取用户输入、解析文件、网络通信等等。Java提供了一个强大的字符串处理工具类——java.lang.String。这个类包含了各种有用的方法&#xff0c;能帮你轻松地处理字符串。在这一节中&#xff0c;我们将介绍几…

基于 SpringBoot+Hikvision SDK 远程查看配置海康网络摄像头配置

写在前面 工作中遇到&#xff0c;简单整理理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式&#xff0c;是对大…

【C++杂货铺】一文带你走进哈希:哈希冲突 | 哈希函数 | 闭散列 | 开散列

文章目录 一、unordered 系列关联式容器二、unordered_map1.1 unordered_map 介绍1.2 unordered_map 的接口说明1.2.1 unordered_map 的构造1.2.2 unordered_map 的容量1.2.3 unordered_map 的迭代器1.2.4 unordered_map 的元素访问1.2.5 unordered_map 的查询1.2.6 unordered_…

【正点原子STM32连载】 第四十二章 IIC实验 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html## 第四…