该协议为自定义协议,模仿了YModem-1K帧结构,每包传输1K数据,最后一包数据根据文件大小决定,为总字节数对1024取整。
该协议用N字节信息块传输,N可以自定义,数据的发送会使用CRC16校验,保证数据传输的正确性。它每传输一个信息块数据时,就会等待接收端回应ACK信号,接收到回应后,才会继续传输下一个信息块,保证数据已经全部接收。且支持了下位机的序列包定位,当漏发了一包数据,或者需要跳转,当前仅支持按照1024字节整数倍进行文件跳转,该协议不包含结束帧,可根据序列号进行判断。文件大小应小于67108864 Bytes,即64Mbyte。
文件发送篇
1、起始帧的数据格式
起始帧并不直接传输文件的数据,而是将文件名与文件的大小放在数据帧中传输,它的帧长=4字节帧头+4字节文件大小+2字节包大小+2字节CRC16校验码+文件名(不定长字符串)。
它的数据结构如下:
AA BB CC DD FileSize[4] PacketSize[2] CRCH CRCL filename[…]
其中AA BB CC DD,表示这个数据帧为起始帧;在帧头后面的FileSize [4]表示文件大小,4个字节高位在前低位在后;PacketSize[2] 表示每包文件数据大小,文件将拆分成多个PacketSize进行传输;CRCH CRCL分别表示16位CRC校验码的高8位与低8位,校验的数据为4字节文件长度+2字节包大小;filename[…]就是文件名,如文件名foo.c,它在数据帧中存放格式为:66 6F 6F 2E 63 00,一定要在文件名最后跟上一个00,表示文件名结束 。
2、数据帧的数据格式
数据帧中会预留PacketSize字节空间用来传输文件数据,它跟起始帧接收差不多,如下:
00 00 data[PacketSize] CRCH CRCL
其中00 00表示第一帧数据帧,当然如果是第二帧数据的话就是:00 01;data[PacketSize]表示存放着PacketSize字节的文件数据;CRCH与CRCL是CRC16校验码的高8位与低8位,校验的数据为data中的数据。
如果文件数据的最后剩余的数据小于PacketSize,假设最后一包序列号为num的数据,剩余n字节数据,且n< PacketSize,则如下结构:
[num] data[n] CRCH CRCL
3、文件传输过程
文件的传输过程,以具体的例子说明。把foo.c,大小为4196Byte(16进制为0x1064)的文件作为传输的对象,拆分为1024byte(PacketSize=1024,16进制为0x0400)一包,则它的传输过程如下:
发送端 接收端
AA BB CC DD 00 00 64 10 04 00 CRCH CRCL "foo.c" >>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
00 00 data[1024] CRCH CRCL >>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
00 01 data[1024] CRCH CRCL >>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
00 02 data[1024] CRCH CRCL >>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
00 03 data[1024] CRCH CRCL >>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
00 04 data[100] CRCH CRCL >>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ACK
传输过程就是上面所示。但是上面传输过程中存在许多通信信号,它们的数值与意义如下表所示:
|
符号 |
数值 |
含义 |
|
ACK |
0x06 |
正常回应 |
|
ERR |
0X07 |
校验错误 |
|
ERR1 |
0x08 |
请求重传序列号包 |
|
CA |
0XFFFF |
传输中止 |
|
|
|
|
还是有几点需要说明下:
1)CA中止传输信号都可以发送,可在需要传输新文件时发送
2)ERR信号,当校验失败的时候,由接收方发送,发送方收到后重传当前序列包。
3)ERR1信号,基本上不可能出现。当出现该信号的时候说明帧错乱,需要重新定位序列帧数据,请求重传,格式为0x08 numH numL ,num为请求的序列包,高字节在前,低字节在后。
4、CRC的计算
采用的是CRC-16-IBM(A001)的CRC校验,它的生成多项式为x16+x12+x5+1。
下面列出两种c语言的计算方法查表和计算。
计算方式:
1 /****************************************************** 2 *函数名称:CRC16RTU 3 *输 入:pszBuf 要校验的数据 4 unLength 校验数据的长 5 *输 出:校验值 6 *功 能:循环冗余校验-16 7 (RTU标准-0xA001) 8 *******************************************************/ 9 u16 CRC16RTU( u8 * pszBuf, u16 unLength) 10 { 11 u16 CRCx=0XFFFF; 12 u32 CRC_count; 13 for(CRC_count=0;CRC_count<unLength;CRC_count++) 14 { 15 int i; 16 CRCx=CRCx^*(pszBuf+CRC_count); 17 18 for(i=0;i<8;i++) 19 { 20 if(CRCx&1) 21 { 22 CRCx>>=1; 23 CRCx^=0xA001; 24 } 25 else 26 { 27 CRCx>>=1; 28 } 29 } 30 } 31 32 return CRCx; 33 }
查表方式:
文件接收篇
准备进入接收模式的时候,发送一帧数据告诉对方已准备好接收(当然也是可以不发该帧数据,让发送方主动发送就可以了)。该协议默认通知发送方已准备好接收数据。
帧格式(3字节): 0XAA 0XBB 0XDD
文件传输无响应:

文件传输强制中断:

文件传输完成:

文件正在传输:
