stm32处理tcp
文章目录
【注意】最后更新于 May 28, 2017,文中内容可能已过时,请谨慎使用。
最近项目要用到stm32和wifi模块,接收处理TCP数据,在项目中遇到了一些问题,在此记录一下。
首先项目把wifi模块配置成透传模式了,所以可以对模块忽略不计,只在板子处理就好。
都知道TCP的传输是分“碎片”(fragment)的,一个完整的报文并不一定是在一个TCP包里传输的,可能是分离在多个报文中。
为了处理这个问题,需要对我们的数据做出一定的规定,有数据起始位和数据长度位,通过这两个控制位来对数据进行接收。
程序的逻辑图如下:
(原谅我的灵魂画法)
处理流程如下:
(1)首先将状态置为默认起始状态,接收一定长度的数据头,接收齐全进行比对。如果数据正确,进入状态2;如果不对,继续接收数据头。其中把数据头区域设置为缓冲区,依次往里读数据,旧数据移除。
(2)在状态二,接收指定长度的字节,转换为int数据,作为状态三接收数据长度的依据。
(3)在此状态,通过串口中断向数据区写入数据,直到接收正确长度的数据。
程序的处理流程相对比较简洁,在程序实现上还是遇到了一点问题,主要是脑子一直考虑不全。
首先我创建一个接收控制部分的缓冲区
|
|
数据的起始部分是四个数字0,需要用一个变量进行记录,统计接收到几个数据,而不能直接通过数组内的数据进行判断。
|
|
使用num进行计数,然后将ctrl的数据依次更新。
等到num==4
的时候数据接收完整,就可以进行状态进行判断了。
|
|
如果数据正确就会进入状态2,否则重新置为状态1,为了方便触发函数,需要将num置为4,保证接收到一个数据就要进行判断一次。
进入状态2直接从串口接收数据,然后读取大小,接收后续的数据。等到数据接收完成触发处理程序即可。
这样似乎程序已经完整了,但是bug就是奇葩。wifi模块偶尔会丢失几个数据,结果就是会把后一帧的完成的数据读到上一帧里面去,然后后面的就全部都错了。
考虑到这样的情况,直接程序进行处理似乎不太方便,但是stm32有定时器啊,这下就方便啦!当程序隔了一定的时间依然没有接收到正确的内容,就该扔的扔,直接处理下一帧数据。
状态如下:
(嗯,再次请求原谅)
首先定义定时器中断相关
|
|
触发函数只需要将一个变量自增即可。 串口中断函数判断变量是不是到达阈值,如果到达阈值,就状态清零,缓冲区清零,还有接收大小清零。
|
|
这样程序就运行比较稳定了,虽然可能会有丢包的现象,但毕竟概率比较低了。