1 背景
在调试项目时发现, 发现仅仅串口传输, 就会遇到多种问题, 层出不穷,故整理如下
1.1 串口中断问题 单字节中断, DMA 空闲中断, 发送不连续.处理不及时
1.2 丢包, 断包, 粘包问题
1.3 驱动与应用耦合太大, 无法愉快的移植
1.4 十六进制与ASCII 码 , 部分开发者傻傻分不清.
初步想法和方案
为了协调上位机与下位机的通信, 想到使用空闲DMA 中断, 可以做到多字节后, 再触发中断, 节省cpu 资源, 然后再和上位机那边规定了通信协议 , 帧头+数据+校验的方式, 就极有可能遇到, 一个数据包分为两段甚至更多段发送, 还要考虑重发机制.
这时候可以写上由帧头+定长, 来实现帧处理的逻辑, 处理不好, 可能会遇到长包漏处理的现象, 这些逻辑性的代码, 实际开发中, 可能会到各种问题, 定好协议后, 调试也会浪费很长很长的时间.
为此, 我试图找一个统一的解决办法. 要么找一个开源方案, 要么自己实现一个
开源方案
网上找到的资料很多, 有很多长篇大论的纯理论上的知识, 过于冗长, 并不适用, 类似于tcp 的包头一样.
后来终于找到一款简约不简单的, 适合于单片机的链路层协议 , 看完之后, 感慨良多, 比我自己写的协议代码优秀太多了, 那天功力又精进了很多.
链接如下 https://github.com/aeo123/upacker
体验
初步体验是按照黑盒逻辑来使用的, 全程没有看源代码,
有以下优点
- 1 不用担心断包, 粘包问题, 错包也能自行过滤
- 2 注册发送, 和帧接收完成回调, 和一个处理循环, 很是方便实用. 初期调试很愉快
- 3 不用去做数据缓冲区, 不用考虑哪里是帧头, 长度, 校验, 等等, 拿来用都有了
以下是部分问题
后来总是时不时的出现不触发帧完成的问题, 排查了半天后发现, 是由于程序使用中, 帧头校验(2bit)过短导致的, 获取了一个错误的帧长度, 没接收满之前, 不会触发帧完成回调, 让我们测试时以为线没接好, 浪费了数个小时.
优化
根据上述的问题, 我在原来四个字节的载波基础上, 增加了两个字节, 分别对头校验, 和数据段校验进行了扩充更改, 这样可以尽可能避免受到错误长度的帧长度,触发不了帧完成了, 数据段校验也由原来的和校验更改为modbus16 rtu - CRC 校验, 更改后的文档上还有部分bug , 还被 同事嘲笑了一番, 所以就不放链接了, 有心的小伙伴可以在github 找到, 文档慎看, 等我有空再更新完整版的介绍文档. 在这里建议自行修改aeo123的源码即可. 改动大约在100个字符以内.
总结
此通信协议不局限于串口, 只是单片机使用最多的是串口. 网络tcp , mqtt 等拿来就用, 也是非常方便的,
使用更改后的协议, 非常好用, 就再也没有遇到各种糟心的通信问题了, 有更多的时间水群聊天摸鱼打游戏看电影看小说写文章逛论坛了