硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1548|回复: 18
收起左侧

[技术讨论] 讨论一下串口解析应该怎么设计比较合理(二)?

  [复制链接]

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
发表于 2024-12-12 17:33:08 | 显示全部楼层 |阅读模式


讨论一下串口解析应该怎么设计比较合理?
https://forum.anfulai.cn/forum.p ... 5&fromuid=32469
(出处: 硬汉嵌入式论坛)





今天我遇到一个第三方的设备,它本身没有重传机制,所以我按照第一种方式进行解析。
有包头包尾checksum和字节长度。

我大概花了一天的时间去写解析函数,思考了一下貌似没办法适配所有情况。

协议如下
Snipaste_2024-12-12_16-44-31.png

然后它没有做重传机制

它的上报数据如下:
[C] 纯文本查看 复制代码
//{0xA5, 0xFC, 0x02, 0x00, 0xA3, 0x9A, 0x0C, 0x00, 0xB1, 0xFA, 0x01, 0xFB, 0xA5, 0xFC, 0x07, 0x00, 0xA0, 0x91, 0x0D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x69, 0x01, 0xFB}


在数据都正确的情况下,怎么解析都是没有问题的。我脑补了几种极端的情况,有没有办法解析?



情况1:
假设帧头发送了两次。这种情况下能否解析?
[C] 纯文本查看 复制代码
//{0xA5, 0xFC,0xA5, 0xFC, 0x02, 0x00, 0xA3, 0x9A, 0x0C, 0x00, 0xB1, 0xXX, 0xXX, 0xFB}


情况2:
假设断帧,能否解析?
[C] 纯文本查看 复制代码
//{0xA5, 0xFC,0xA5, 0xFC, 0x02, 0x00, 0xA3, 0x9A, 0x0C, 0x00, 0xB1, 0xXX, 0xXX}

[C] 纯文本查看 复制代码
//{0xFB}


情况3:
假设长度字节出错,能否解析?如何分辨是断帧还是长度字节出错?(例如这里长度字节变成了0X0102明显大大超出)


[C] 纯文本查看 复制代码
//{0xA5, 0xFC,0xA5, 0xFC, 0x02, 0x01, 0xA3, 0x9A, 0x0C, 0x00, 0xFB, 0xXX, 0xXX, 0xFB}



如果依靠包尾去判断情况2和情况3,那么如果数据段里面有字节和包尾一样,如何解析?
[C] 纯文本查看 复制代码
//{0xA5, 0xFC,0xA5, 0xFC, 0x02, 0x01, 0xA3, 0x9A, 0x0C, 0x00, 0xFB, 0xXX, 0xXX, 0xFB}






回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
 楼主| 发表于 2024-12-12 17:41:57 | 显示全部楼层
目前我就是无法判断是长度字节出错,还是断帧。
当这两种情况发生的时候,现象就是接受到的长度小于通过长度字节计算的理论的长度。
断帧的话需要不丢弃数据等待数据的到来,而长度字节出错,需要丢弃数据。
我无法兼容这两种情况。

如果我依靠包尾去辅助判断的话,仿佛又没办法兼容数据段里面包含包尾的情况。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-12-13 01:19:10 | 显示全部楼层
这种的实际上是设备限制了稳定性更好的通信机制。

这种通信还是Modbus做的稳定些,有CRC校验判断帧错,还有字节数判断和帧间隔判断。
回复

使用道具 举报

25

主题

232

回帖

307

积分

高级会员

积分
307
QQ
发表于 2024-12-13 10:06:20 | 显示全部楼层
仅针对情况1帧头发送了两次显然是可以特殊处理的,正常解析流下,原本的数据长度部分出现 0xA5, 0xFC帧头显然太可疑了。但是我觉得如果不是确实发现这种情况,不如直接当错误帧弃掉。

情况2,断续帧有很简单的方法,我所有的通信都有这个机制
屏幕截图 2024-12-13 095024.png

情况3,长度字节出错,直接弃帧吧,如果长度字节出错,那么显然数据字节也不可靠,无法判断帧尾究竟是帧尾还是数据字节出错产生的假帧尾。
回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
 楼主| 发表于 2024-12-13 10:10:40 | 显示全部楼层
yono 发表于 2024-12-13 10:06
仅针对情况1帧头发送了两次显然是可以特殊处理的,正常解析流下,原本的数据长度部分出现 0xA5, 0xFC帧头显 ...

嗯,我最后也是引入了一个参数,最大长度。
如果接收到断帧之后,长度小于最大长度就继续接收,如果大于就判断出错,去清理buff。

回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-12-13 10:35:55 | 显示全部楼层
yono 发表于 2024-12-13 10:06
仅针对情况1帧头发送了两次显然是可以特殊处理的,正常解析流下,原本的数据长度部分出现 0xA5, 0xFC帧头显 ...

你这个图是通过什么软件制作的啊?
回复

使用道具 举报

25

主题

232

回帖

307

积分

高级会员

积分
307
QQ
发表于 2024-12-13 10:36:59 | 显示全部楼层
会飞的猪_2020 发表于 2024-12-13 10:10
嗯,我最后也是引入了一个参数,最大长度。
如果接收到断帧之后,长度小于最大长度就继续接收,如果大于 ...

我的思考是像按键消抖,做数据帧的消抖,确立电平和无效电平的判断逻辑
回复

使用道具 举报

21

主题

481

回帖

544

积分

金牌会员

积分
544
发表于 2024-12-13 11:02:35 | 显示全部楼层
这种类型的发送/接收的实现,通常用DMA+IDLE中断模式整体处理nbytes,也不会占用过多CPU中断进出时间
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-12-13 11:47:25 | 显示全部楼层
这个还得靠协议完善才行,比如加入转码机制,只有帧头能出现特定的字符,比如如果帧头是0X55的话
(1)发送方:如遇0x55,转码为0xFF 0x00;如遇0xFF,转码为0xFF 0xFF。
(2)接收方:如遇0xFF 0xFF,转码为0xFF;如遇0xFF 0x00,转码为0x55。
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-12-13 11:49:00 | 显示全部楼层
还得完善协议才行,比如除了帧起始字节(FS)以外,帧内的数据不允许出现与FS一致的数值,如果帧头是0x55的话
发送方:如遇0x55,转码为0xFF 0x00;如遇0xFF,转码为0xFF 0xFF。
接收方:如遇0xFF 0xFF,转码为0xFF;如遇0xFF 0x00,转码为0x55。
回复

使用道具 举报

2

主题

9

回帖

15

积分

新手上路

积分
15
发表于 2024-12-13 11:49:27 | 显示全部楼层
回复不了什么鬼
回复

使用道具 举报

4

主题

412

回帖

424

积分

高级会员

积分
424
发表于 2024-12-13 14:22:04 | 显示全部楼层
DMA+IDLE+环形缓冲更爽
回复

使用道具 举报

24

主题

365

回帖

437

积分

高级会员

积分
437
发表于 2024-12-13 15:55:04 | 显示全部楼层
用COBS把原始数据包打包一下,再用0x00作为包间隔,方便又可靠。甚至你还有把打包后的所有数据都加一个值M,用M作为包间隔

高效可靠的数据字节编码算法COBS,可用于串口通信
https://forum.anfulai.cn/forum.p ... 9&fromuid=41790
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
 楼主| 发表于 2024-12-13 16:59:26 | 显示全部楼层
tovinz 发表于 2024-12-13 15:55
用COBS把原始数据包打包一下,再用0x00作为包间隔,方便又可靠。甚至你还有把打包后的所有数据都加一个值M ...

我是对接了第三方的设备,所以协议上没办法选择,只能是适配它的。
回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
 楼主| 发表于 2024-12-13 17:00:53 | 显示全部楼层
Piii 发表于 2024-12-13 11:47
这个还得靠协议完善才行,比如加入转码机制,只有帧头能出现特定的字符,比如如果帧头是0X55的话
(1)发 ...

是的,稳定性还是需要依靠协议完善。
目前我想到的办法只能是限制最大接收的字节数,去判断。
回复

使用道具 举报

25

主题

232

回帖

307

积分

高级会员

积分
307
QQ
发表于 2024-12-16 16:24:33 | 显示全部楼层
正义属于世界 发表于 2024-12-13 10:35
你这个图是通过什么软件制作的啊?

excalidraw 开源白板,中文支持你可以自己探索一下
回复

使用道具 举报

2

主题

71

回帖

77

积分

初级会员

积分
77
发表于 2024-12-16 17:39:43 | 显示全部楼层
2个字节的作为包长的确实需要限制包长,2个字节如果出错了可能要一直读60k才能丢弃
如果是1个字节作为包长,出错的帧最多读255字节即可校验和丢弃
回复

使用道具 举报

2

主题

71

回帖

77

积分

初级会员

积分
77
发表于 2024-12-16 17:44:24 | 显示全部楼层
楼上的COBS如果两边都支持也不错,比自己造轮子方便
空闲分包有个隐藏问题是速度不可能做高
回复

使用道具 举报

24

主题

365

回帖

437

积分

高级会员

积分
437
发表于 2024-12-20 16:27:38 | 显示全部楼层
踩姑娘的小蘑菇 发表于 2024-12-16 17:44
楼上的COBS如果两边都支持也不错,比自己造轮子方便
空闲分包有个隐藏问题是速度不可能做高

是这样的,因为不需要分包时间间隔,使用流式传输的方式使得串口链路利用率相当高。我之前测试应用层数据的收发速率可以达到串口波特率的98%以上,挺适合两个单片机之间的高速数据包通信
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 02:49 , Processed in 0.053315 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表