stm32 打造自己环形队列

stm32 esp8266 ota系列文章:
stm32 esp8266 ota-快速搭建web服务器之docker安装openresty
stm32 esp8266 ota升级-tcp模拟http
stm32 esp8266 ota升级-hex合并-烧录-bin生成
stm32 esp8266 ota升级-qt bin文件处理工具
stm32 esp8266 ota升级-自建mqtt和文件服务器动态AB面方式
stm32 esp8266 ota升级-自建mqtt和文件服务器全量升级

stm32 打造自己环形队列

本环形队列实现以数组形式批量写入和读取队列中数据。

写入数据时,对于队列剩余空间不足时,可以选择强制覆盖写入(会有覆盖部分原队列数据,请根据自己实现需要操作);不覆盖,则不会写入;

读取数据时,如果超过队列中已存数据长度,则读取实际大小;没有超过,则正常读取。

本环形队列可用作串口数据缓存接收,尤为适用于有具体协议格式数据,方便查找TAG标识进行定位。但对于串口采用DMA方式,接收大量无协议格式的数据,暂不适用。

以上理解,如有误,请指正。

环境介绍

硬件

  1. stm32F103C8t6系列板子;

软件

app 程序

环形队列测试程序

环形队列原理

请参考数据结构–环形队列的介绍与实现 博文,感谢博主分享;

环形队列具体实现

枚举和结构体定义

image-20230112093430016

队列初始化

image-20230112093522891

队列判断空和满

image-20230112093659033

以数组形式写入队列

对于写入数组数据大小大于队列剩余空间时,

1)如果forceWrite=true,则有数据覆盖,返回RINGQUEUE_FORCE_OVERWRITE_SUCCESS,此时队列大小为queueSize;

2)如果forceWrite=false,则不做处理,直接返回RINGQUEUE_OVERWRITE_DATA_FAIL;

image-20230112093835566

从队列以数组形式读取

image-20230112094100549

测试

测试所用数据

char data[64] = "12345678abcdef";   //14个字符

初始化队列,队列大小为16

//初始化队列
ringQueue_init(&testRQ, rq_buf, 16);

正常读写测试

image-20230112101901398

测试日志

1 正常读写测试

待写入数据为:12345678abcdef

+++++++++++++以数组形式写入队列+++++++++++++
写入后头位置、尾位置和队列中已存数据大小 front:0,rear:14,dataLength:14
RINGQUEUE_STATUS_e val:1  //对比枚举定义,RINGQUEUE_WRITE_SUCCESS=1

+++++++++从队列以数组形式读取++++++++++
读取后头位置、尾位置和队列中已存数据大小 front:14,rear:14,dataLength:0
data:12345678abcdef,length:14

----------------------------------------

异常读写

超队列大小写测试

对于写入数据超过队列大小了,无论强制写与否,都返回RINGQUEUE_SIZE_EXCEEDED_FAIL,不能写入。对于这种情况,请增大队列缓存区大小。

image-20230112175525633

日志:

2 异常读写测试 

刚开始初始头位置、尾位置和队列中已存数据大小 front:0,rear:0,dataLength:0 

2.1.1 写入20字节超过队列大小,不强制,返回RINGQUEUE_SIZE_EXCEEDED_FAIL 5

RINGQUEUE_STATUS_e val:5
forceWrite==false 写入后头位置、尾位置和队列中已存数据大小 front:0,rear:0,dataLength:0 

2.1.2 写入20字节超过队列大小,强制,返回RINGQUEUE_SIZE_EXCEEDED_FAIL

RINGQUEUE_STATUS_e val:5
forceWrite==true 写入后头位置、尾位置和队列中已存数据大小 front:0,rear:0,dataLength:0 
多次写入数据,达到覆盖数据测试

队列剩余空间可以容纳待写入数据时,正常写入;当写入数据大于可容纳数据时,强制写会出现数据覆盖;不强制,则不能写入,返回失败。

image-20230112180333122

日志:

2.2 多次写入数据,达到覆盖数据测试,forceWrite==false时,不覆盖;true时覆盖 

2.2.1 写入10字节未超过队列大小,强制,返回RINGQUEUE_WRITE_SUCCESS,队列数据10字节

RINGQUEUE_STATUS_e val:1

forceWrite==true 写入后头位置、尾位置和队列中已存数据大小 front:0,rear:10,dataLength:10 

2.2.2 写入14字节超过队列剩余可写空间大小6字节,强制,返回RINGQUEUE_FORCE_OVERWRITE_SUCCESS,队满会覆盖掉原Front位置后的8个字节\r

RINGQUEUE_STATUS_e val:7

forceWrite==false 写入后头位置、尾位置和队列中已存数据大小 front:8,rear:8,dataLength:16 
多次读数据,读取长度大于队列或队列中已有数据大小

读取数据长度小于队列已存数据长度时,正常读取;

读取长度大于队列或队列中已有数据大小时,读取出队列中已有数据;

image-20230112181241691

日志:

2.3 多次读数据,读取长度大于队列或队列中已有数据大小时,则读取实际的队列中已有数据大小\r

2.3.1 读取10字节

data:ab12345678,length:10

读取长度大于dataLength,头位置、尾位置和队列中已存数据大小 front:2,rear:8,dataLength:6 

2.3.2 读取10字节

data:abcdef,length:6

读取长度大于dataLength,头位置、尾位置和队列中已存数据大小 front:8,rear:8,dataLength:0 

队列为空时读取

队列为空时,读取数据为NULL,长度为0。程序也做了异常处理。

正确用法是,在读取时,应该做判空处理。不为空时,再读取。

image-20230112181553293

日志:

2.4 队列为空时读取\

队列为空时读取,头位置、尾位置和队列中已存数据大小 front:0,rear:0,dataLength:0 

data:,length:0

总结

通过对循环队列讲解,用户可根据自己的实际情况,修改代码,打造适用于自己项目的循环队列。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心之雅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值