协议解析随想

本文探讨了在多路通信协议中如何实现统一解析机制,通过函数指针和多态,构建了一个可重用的模块,支持多个数据通道和解析协议。文章详细介绍了接收、检查、解析和发送数据的解耦架构,以及在ACK机制下如何避免重复数据帧的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做一个项目,其中用到了多路通信协议,做下总结吧,一边以后自己查阅。

 

最常见就是一个通信通道,比如:UART,SPI,本地以太网等。一个数据流通道,一种解析模块。这种结构最简单了,

开辟一个接收缓存,然后check解析即可,没啥可说的。如果是N个通道,一种解析协议,我们怎么做?先考虑简单

的情况,就是解析发送,没有ACK等机制,驱动层各自收各自的,然后解析层可重入(即用临时变量传入),然后

各个解析模块都调用同一个解析“函数”,如果有重传机制呢?举例:

1、有三个数据通道,4G,本地以太网,调试串口;

2、有重传机制;

3、协议完成一致;

基于上面的考虑,我在想怎么做到用一个解析驱动去包容三种,而不是写了三遍代码。思路如下:

1、运用函数指针实现多态;

2、整体的接收、解析、发送结构一致;

看下接口定义及初始化:

再看下最终的调用:

是不是很整齐。原来这块,我没有想着把它封装成一个模块,后来同事那边也要用,于是就把它封装成了一个

单独的模块:

需要用户传入的:

提供的对外接口:

这样封装之后,就可以很方便的被其他模块调用。这个模块只是用与多通道多解析,如果是一个通道多解析,则需要

运用peek而不是read,这个就留给诸位思考了。

 

2019.07.10

    今天在看以前的代码,突然想到一个解析上存在的问题。

我的解析架构如下:

同一个状态机里面包含如下功能:

不停的从缓存区check一帧数据;

如果check到了,则进入解析状态;

如果带有ACK重发机制,则上面存在如下问题:

当上一帧解析未完成时候,下一帧数据到来,由于没有收到ACK,则重发,这样就会导致缓存里面有大量的重复性

数据帧。

我的解析思路如下:

1、接收线程就是不停的入队;

2、check线程就是不停的去check一帧数据,如果check到了,则放进接收缓存队列(链表实现);

3、解析线程就是不停的从接收缓存队列里面读取数据帧,去解析,然后把要发送的数据放进发送缓存队列(链表实现);

4、发送缓存就是不停的从发送缓存队列获取数据,然后发送。

如果涉及到ACK机制,这里面需要用到信号量去做同步。当然了,这种架构需要有一些RAM支持,对于复杂的项目比较合适。

 

2019.07.12

这几天在改写解析架构,把接收数据,check数据,解析数据全部,发送数据,四个task全部解耦。思路就是前面所写。

下面我来说一说我的实现过程。

1、实现一个简单的list内存池,由于数据帧大小未知,因此在初始化时候可设置,如果带有硬件带有MMU,那就更简单了

这里只保留一个指针,在check里面动态绑定即可;由于我是裸跑,为了减少内存碎片化,初始化时候,就绑定了用户指定

大小的buffer,然后用单链表连接成一个内存池;

2、有一个freelist指向一个空闲内存池,txlist指向发送链表,rxlist指向接收链表,

check线程就是不停的从底层接收缓存读取一个完成的数据帧,然后从空闲链表获取一个Item,数据复制完后,

放到rxlist队尾;解析线程就是不停的从rxlsit对手获取一个Item,然后去做解析,解析完成,把它释放给空闲链表;

发送线程就是不停的从txlist的对首获取一个Item,然后发送完成后,把它释放给空闲链表;

 

实现代码,我就补贴了,太简单了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值