UART学习笔记二:如何去check数据帧

接着以前的文章(UART学习笔记一),继续聊聊这个话题。上次的文章分析了如果去

接收数据,这章分析下如果去check一帧数据。如果想要check一帧数据,就要考虑两种情况:

1)数据帧接收完毕,意思就是说buffer里面有一帧完整的数据;

2)数据帧暂时没有接收完毕,比如:帧头、校验、帧尾,目前只收到了帧头;

上面两种情况和底层驱动实现方式直接相关:

1)Timer_out方式;

2)边接收边解析,队列缓存方式;

首先来说第一种情况:

底层驱动利用TIMER_OUT方式,这个是时候,check_function(...)可以认为已经收到一帧

“完整”数据。然后就去按着常规的方式去解析:

1)找帧头,如果成功则执行步骤2,否则丢弃;

2)找帧尾,如果成功则执行步骤三,否则丢弃;

3)检查校验,如果成功则通知协议解析,否则丢弃;

如果成功,丢给协议解析函数,否则直接丢弃,并清空缓存;

这种方式很简单,基本没什么难度,按着帧格式校验就可以。

再来看看另外一种:

底层驱动负责入队操作,check_function负责出队操作,同时负责检查,其编写逻辑就不能

按着上面的步骤直接操作了。要利用状态机的思维,首先定义出几个状态,然后根据状态去

做相应的事情。

enum{

FSM_START = 0,

FSM_WAIT_HEAD,

FSM_WAIT_TAIL,

FSM_WAIT_USER_READ

};

FSM_START:做一些初始化工作,必须保留。

FSM_WAIT_HEAD:查找帧头,其逻辑如下:

如果接收数据 < 帧头数据个数,把数据保存到缓存,直接返回;

如果没有找到帧头,则保留缓存区最后的帧头数据个数-1个数据,其它丢弃,返回;

如果找到帧头,则直接丢弃帧头前面数据,同时把帧头以后数据复制到缓存头开始处

(这是为了处理方便,当然也可以用环形的处理方式),状态机跳到FSM_WAIT_TAIL。

FSM_WAIT_TAIL:等待帧尾,其逻辑如下:

如果缓存数据<计算出的帧长总个数 保存数据,直接返回;

检验帧尾,如果错误,则丢弃缓存第一个字节,goto到FSM_WAIT_HEAD;

校验帧校验位,如果错误,则丢弃缓存第一个字节,goto到FSM_WAIT_HEAD;

跳转到FSM_WAIT_USER_READ:什么都不干,不能出队,也不能对缓存进行操作,

就是直接返回 true;(为了做同步)


用户检查到true,就会调用read_data(。。。)把检查到一帧数据,拷贝到用户缓存区,

同时自动复位状态机;


注意点:

1、丢弃缓存第一个字节,goto到FSM_WAIT_HEAD,是为了防止由于上帧数据接收到

一部分(后面的数据丢失),引起下帧数据错误问题;

2、最好有个接收超时,然后整帧校验,复位状态机;

3、用goto是为了更好的解决逻辑问题,使逻辑更清晰;



有时间再去说说如果去做协议分析。以上观点都是本人愚见,还请大神们不吝指教。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值