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

这篇具有很好参考价值的文章主要介绍了消息队列缓存,以蓝牙消息服务为例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

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

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

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

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

学习交流请发邮件 1280253714@qq.com

原理讲解

队列采用"生产者-消费者"模式,

当接收数据时,生产者即为外部输入,输入的消息入列;消费者即为消息处理函数,处理消息前先出列,然后消费者处理出列的消息

当发送数据时,生产者为消息产生的任务,该任务将产生的消息入列;消费者为消息发送任务,该任务将待发送的消息出列并发送。

接口

接收消息接口

以蓝牙接收消息服务为例

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机

接收消息处理接口

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

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机

待发送消息装载接口

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

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机

待发送消息发送接口

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

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机

代码

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));
}

一个图图

消息队列缓存,以蓝牙消息服务为例,BLE,C语言内核深度解析,缓存,单片机文章来源地址https://www.toymoban.com/news/detail-724552.html

到了这里,关于消息队列缓存,以蓝牙消息服务为例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手动清除RabbitMQ队列的消息缓存

           在个人的springboot项目中使用到了rabbitmq作为消息队列中间件,但是在项目的调试过程中出现了某些错误,导致rabbitmq的生产者端循环产生了多条消息给消费者,而消费者又因为该错误无法及时将消息处理掉,所以在消费端积压了多条消息;在修复了错误重启项目后

    2024年02月11日
    浏览(41)
  • Redisson实现简单消息队列:优雅解决缓存清理冲突

    在项目中,缓存是提高应用性能和响应速度的关键手段之一。然而,当多个模块在短时间内发布工单并且需要清理同一个接口的缓存时,容易引发缓存清理冲突,导致缓存失效的问题。为了解决这一难题,我们采用Redisson的消息队列功能,实现了一个简单而高效的消息队列,

    2024年02月16日
    浏览(38)
  • HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核基础-消息队列queue

    队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务

    2024年02月20日
    浏览(49)
  • Flutter:BLE蓝牙开发

    说明: 使用flutter_blue_plus插件实现低功耗蓝牙开发。 一、添加蓝牙权限: 1.Android网络权限(工程/android/app/src/main/AndroidManifest.xml): 2.iOS蓝牙权限(工程/ios/Runner/Info.plist): 二、实现扫描/连接/接收BLE设备数据: 1.添加flutter_blue_plus插件依赖,在pubspec.yaml中: 2.实现BLE蓝牙设备扫

    2024年02月11日
    浏览(44)
  • 蓝牙协议栈&BLE

    这阵子用到蓝牙比较多,想写一个专栏专门讲解蓝牙协议及其应用,本篇是第一篇文章,讲解低功耗蓝牙和蓝牙协议栈。 参考网上各大神文章,及瑞萨的文章,参考GPT,并且加入了一些本人的理解。 图片部分源自网络,侵删。 有纰漏请指出,转载请说明。 学习交流请发邮件

    2024年02月09日
    浏览(49)
  • BLE蓝牙协议栈分析

    Controller实现射频相关的模拟和数字部分,完成最基本的数据发送和接收,Controller对外接口是天线,对内接口是主机控制器接口HCI(Hostcontroller interface); 控制器包含物理层PHY(physicallayer),链路层LL(linker layer),直接测试模式DTM(Direct Test mode)以及主机控制器接口HCI。

    2024年02月13日
    浏览(55)
  • 蓝牙BLE学习-安全

    蓝牙标准规定了5种基本的安全服务 身份验证:根据通信设备的蓝牙地址验证其身份。蓝牙不提供本地用户身份验证。 保密性:确保只有授权的设备才能访问和查看传输的数据,防止窃听造成的信息泄露。 授权(Authorization):在允许设备使用某项服务之前,确保该设备已被授权,从

    2024年02月19日
    浏览(47)
  • Android蓝牙BLE开发

    最近正在研究Android的蓝牙BLE开发学习,以下是自己做的个人总结 首先得说明什么是低功耗蓝牙BLE,BLE的全称为Bluetooth low energy(或称Blooth LE,BLE),从英文全称便可以知晓其是一种低功耗的蓝牙技术,是蓝牙技术联盟设计和销售的一种个人局域网技术,旨在用于医疗保健、运

    2023年04月09日
    浏览(45)
  • 物联协议整理——蓝牙BLE

    最近公司很多物联设备都使用BLE蓝牙和ZigBee通信,中间对设备功耗要求很高,补充下相关知识。 PHY层 (Physical layer物理层)。PHY层用来指定BLE所用的无线频段,调制解调方式和方法等。PHY层做得好不好,直接决定整个BLE芯片的功耗,灵敏度以及selectivity等射频指标。 LL层 (

    2024年02月06日
    浏览(53)
  • 蓝牙 - 关于BLE的安全连接

    A Basic Introduction to BLE 4.x Security 引言 Bluetooth Low Energy (BLE)正在迅速成为当今最常用的无线标准之一。同样地,它也越来越多地被用于传输敏感信息的应用中。因此,希望将BLE集成到其产品中的设计者应该了解这项技术的安全特性和限制。本文试图对这些功能做一个基本的概

    2024年02月01日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包