您好,欢迎来到画鸵萌宠网。
搜索
您的当前位置:首页Xmodem通信

Xmodem通信

来源:画鸵萌宠网
Xmodem通信

谢诗义

1 2

教学重点 作业

2.1 求0,1,2…127的CRC

2.2 在超级输入如下命令以便进行XMODEM接收状态,

2.2.1 命令:xmodemrec

2.2.2 完成以后,应指示XMODEM接收是否正确,及接收到文件长度 2.3 在超级终端下输入如下命令进入XMODEM发送状态

2.3.1 命令:xmodemsend

2.3.2 发送完成以后,应指示发送是否正确

Xmodem协议

3.1 Xmodem协议是一种文件传输协议,文件传输的要求

3.1.1 文件应分块传输,每个块有统一大小 3.1.2 有重传机制:当发送方发送一个块时,它会自动的在每个块后附加上几个字节

的校验字段,当接收方收到该块后,会采用发送方同样的计算方法进行校验,当校验正确时,会要求发送方继续传输下一分块,当校验不正确时,会要求发送方重新传输这一分块

3.1.3 当文件传输结速时,应明确告诉对方:文件传输已经结束 3.2 内容:

3.2.1 Xmodem协议是什么

XMODEM协议是一种串口通信中广泛用到的异步文件传输协议。分为标准Xmodem和1k-Xmodem两种,前者以128字节块的形式传输数据,后者字节块为1k即1024字节,并且每个块都使用一个校验字段来进行错误检测。在校验过程中如果接收方收到的校验字段与发送方传过来的的校验字段相同时,接收方就向发送方发送一个确认字节(ACK)。

除了Xmodem,还有Ymodem,Zmodem协议。他们的协议内容和Xmodem类似,不同的是Ymodem允许批处理文件传输,效率更高;Zmodem则是改进的了Xmodem,它只需要对损坏的块进行重发,其它正确的块不需要发送确认字节。减少了通信量

3.2.2 Xmodem协议相关控制字符

SOH 0x01 STX 0x02 EOT 0x04 NAK 0x15 CAN 0x18 CTRLZ 0x1A

3.2.3 标准Xmodem协议(每个数据包含有128字节数据)帧格式

| SOH(1) |信息包序号(1) | 信息包序号的补码(1) | 数据区段(128) | 校验(1/2) | |_______|____________|___________________|_____________ |____________| 注:每个字段后的数据表示字节数:也就是说SOH字段占一个字节,数据区字段占128字节,校验占1个或2个字段

如果是和校验,校验字段是1个字节,如果是CRC校验,则是2个字节 信息包的初始序号是1,第二个包的序号则是2,第255个包的下一个包的序号是0

对于标准Xmodem协议来说,如果传送的文件不是128的整数倍,那么最后一个数据包的有效内容肯定小于帧长,不足的部分需要用CTRL-Z(0x1A)来填充。

3.2.4 1k-Xmodem(每个数据包含有1024字节数据)帧格式(除数据字段是1024

字节外,其它与标准XMODEM相同)

| STX (1)| 信息包序号(1) | 信息包序号的补码(1) | 数据区段(1024) | 校验(1/2)

3

|

|_______|_____________|___________________|______________ |_______| 3.2.5 传输启动方式

传输由接收方启动,方法是接收方向发送方发送\"C\"或者NAK(注意哦,这里提到的NAK是用来启动传输的。以下我们会看到NAK还可以用来对数据产生重传的机制)。当发送方收到\"C\"或者NAK后,才正式开始向接收方发送数据帧。

那么发‟C‟与发NAK有什么差别?

接收方发送NAK信号表示接收方打算用累加和校验; 接收方发送字符\"C\"则表示接收方打算使用CRC校验。 3.2.6 传输过程

当接收方发送的第一个\"C\"或者NAK到达发送方后,发送方认为可以发送第一个数据包,传输开始启动。发送方接着应该将数据以每次128字节的加上包头(SOH/STX),包号,包号补码,末尾加上校验字段,打包成帧格式传送。 发送方发送了一个包后,就一直等待接收方的应答信号。一般来说,应答信号分为三种:ACK,NAK,CAN

A.如果发送方收到接收方传来的ACK确认,就认为数据包被接收方正确接收,并且接收方要求发送方继续发送下一个包,此时,如果发送方还有数据要发送,那么发送方可以真真切切发送下一个包,但如果此时文件已传输完成,发送方应发送EOT(end of transmit)信号;接收方应以ACK进行确认

B.如果发送方收到接收方传来的NAK(这里,NAK用来告诉发送方重传,不是用来启动传输)字节,则表示接收方请求发送方重发刚才的数据包;

C.如果发送方收到接收方传来的CAN字节(cancel),则表示接收方请求无条件停止传输,发送方收到CAN后,不需要再发送 EOT确认(因为接收方已经不想理它了,呵呵), 3.2.7 如何结束传输

虽然数据包是以 SOH 来标志一个信息包的起始的,但在 SOH 位置上如果出现EOT则表示数据传输结束,再也没有数据传过来(所以像ACK,NAK,CAN这样的包,其包长是一个字节)

3.2.8 接收方如何对接收到的包进行确认

接收方收到一个包之后,首先应确认数据包序号的完整性:包括两个方面: 首先序号是否互补:通过对数据包序号取补,然后和数据包序号的补码异或,结果为0表示正确,结果不为0则发送NAK请求重传

其次是确认数据包序号是否为期望的序号。如果不是期望得到的数据包序号,说明发生严重错误,应该发送一个 CAN 来中止传输

如果接收到的数据包的包序号和前一包相同,那么接收方会忽略这个重复包,向发送方发出 ACK ,准备接收下一个包。

接收方确认了信息包序号的完整性和是正确期望的后,只对 128 字节的数据区段进行校验,结果与帧中最后两个字节(CRC)比较,相同发送 ACK,不同即表明CRC有错误,此时应向发送方发送 NAK. 另外发送方发送的第一个包的序号必须是1 3.2.9 校验和的说明

Xmodem协议支持2种校验,它们是累加和与CRC校验

当接收方一开始启动传输时发送的是NAK,表示它希望以累加和方式校验 当接收方一开始启动传输时发送的是字符“C”,表示它希望以CRC方式校验

3.3 框图

3.4 4

CRC原理

4.1 生成多项

CRC8=X8+X5+X4+1

CRC-CCITT=X16+X12+X5+1 CRC12=X12+X11+X3+X2+1 CRC16=X16+X15+X5+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

4.2

原理

首先回想一下和校验:和校验实际上是把被校验串中的每字节加起来,和即作为此串的校验字段.

CRC则是把被被校验串看成一个数,并在此数后加上两个字节的0,用此数去除以一个被称为生成多项式的一个数,其余数则作为此串的校验字段.

标准xmodem的生成多项式是x16+x12+x5+1,用二进制表示则是10001000000100001 单字节CRC计算实例

5.1 单字节CRC计算实例

当要求一个串的CRC时,必须在此串后添加两个字节的0,然后用新生成的串去除以生成多项式(10001000000100001),所得余数则是此串的CRC, 假设我们要计算数值3的CRC,必须在3后添加两个字节的0

10001000000100001 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 <1>

1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1

<2>

--------------------------------------------------------------------- <3>

1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 <4>

1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0

<5>

-------------------------------------------------------------------------- <6>

1 1 0 0 0 0 0 1 1 0 0 0 1 1 <7>

0x3063 <8>

5

0 1

6

0x30是CRC高位,0x63是CRC的低位 说明:

<1>:前一组数表示生成多项式,即x16+x12+x5+1, 或者说是除数项.后一组数表示数值3后加两个0字节,表示被除数项

<2>:因为除法总是从高位开始,所以这行即是<1>中的除数项 <4>:表示<1>减去<2>(不过这里的减是按位异或),并补充 <5>:是<1>中除数项

<7>:与<4>减去<5>所得结果(不过这里的减是按位异或) <8>:把<7>中二进制化为十六进制 注意:CRC是两字节的

5.2 单字节CRC表(此表是按上面方法计算而得) static const unsigned short T[256]= { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 0x2462,0x3443,0x0420,0x1401,0xe6,0x74c7,0x44a4,0x85, 0xa56a,0xbb,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 0xc9cc,0xd9ed,0xe98e,0xf9af,0x48,0x9969,0xa90a,0xb92b, 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 0xb5ea,0xa5cb,0x95a8,0x85,0xf56e,0xef,0xd52c,0xc50d, 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x47,0x24,0x4405, 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0xe9,0xb98a,0xa9ab, 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 0x4a75,0x5a,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 0x7c26,0x6c07,0x5c,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 }; 5.3

多字节CRC的算法 譬如:要求X1 x2 ....... xn-1 xn的CRC时,先要在此串后加两个字节的0,即被除数为如下串 X1 x2 ....... xn-1 xn 0 0 <1> 假设X1 x2 ....... xn-1的CRC为crch(CRC的高字节),crcl(CRC的低字节),意味着:第<2>作为被除数,并去除以生成多项式时,其余数是crch,crcl X1 x2 ....... xn-1 0 0 <2> Crch crcl <3>

X1 X1

x2 x2

....... .......

xn-1 xn-1

xn Crch ^xn xn Crch^xn Crch^xn Crch^xn

0

0

crcl crcl 0

0

0

<4> <5> <6> <7>

<8> <9>

0 T(Crch^xn)

crcl 0 <10> T(Crch^xn)^(crcl<<8) <11>

<1>:由于要求的是x1 x2……xn-1 xn的CRC,所认在后面加了两个字节的0作为被除数 <2>与<3>:假设x1 x2 ….xn-1的CRC是Crch与crcl,注意在求CRC过程中,在x1 x2 …..xn-1的后面同样加了两个0字节

<4>与<5>:当<2>除以生成多项式得到的余数是Crch与crcl时,则<4>除以生成多项式得

余数肯定时Crch ^ xn与crcl

<6>与<7>:由于我们的被除数实现上是<6>,所以余数也变成了<7>.由于<7>是三个字节,

所以可以继续被生成多项式除.

<8>与<9>:当<8>作被除数时,可通过上面的表查得其余数.

<10>与<11>:由<8>与<9>可推出<10>与<11>,而<10>即就是<7>,所以当被除数是<1>时,

余数是<11> 7 递推算法

unsigned short crc16_ccitt(const unsigned char *buf, int len) {

register int counter;

register unsigned short crc = 0;

for( counter = 0; counter < len; counter++) crc = T[((crc>>8) ^ *buf++) & 0xFF] ^(crc<<8); return crc; }

8 CRC计算实例:求0xff 0xff 两字节串的CRC

9 XMODEM接收流程图

初始化接收文件长度Len=0初始化包序号Num=1初始化接收文件缓冲区的首指针sp每秒发一次C,收到字符时退出等待接收第一个字符是EOT?发ACK并退出接收一帧中余下的132字节序号是否正确发CAN并退出CRC是否正确发NAKNum++;Len=len+128把数据复制到spSp=sp+128发ACK 10 XMODEM接收函数 int len=0;

void xmoderec() {

unsigned char num=1; unsigned char arr[140]; unsigned char *sp; len=0; sp=(unsigned char *)0x20000000; AT91C_BASE_SYS->ST_PIMR=0; while(1) { if ((AT91C_BASE_SYS->DBGU_CSR & 0x01)==0x01) break; if ((AT91C_BASE_SYS->ST_SR & 0x01)==0x01) AT91C_BASE_SYS->DBGU_THR='C'; } while(1) { while((AT91C_BASE_SYS->DBGU_CSR & 0x01)==0x0); ch=AT91C_BASE_SYS->DBGU_RHR; if (ch==EOH) { AT91C_BASE_SYS->DBGU_THR=ACK; return; } for(i=0;i<132;i++) { while((AT91C_BASE_SYS->DBGU_CSR & 0x01)==0x0); arr[i]=AT91C_BASE_SYS->DBGU_RHR; } if ((((arr[0]^arr[1])==0xff)&&(arr[0]==num))==0) { AT91C_BASE_SYS->DBGU_THR=CAN; return; } if (crc16_ccitt(&arr[2],128)!=((arr[130]<<8)+arr[131])) { AT91C_BASE_SYS->DBGU_THR=NAK; } else { num++; len=len+128; for(i=0;i<128;i++) { *sp++=arr[i+2]; } AT91C_BASE_SYS->DBGU_THR=ACK; } } }

11 发送 Void xmodemsend() {

Unsigned char temp; Unsigned char arr[133

0];

Unsigned int sendlen=0; Unsigned char I; unsigned char *sp; unsigned short crc; sp=(unsigned char *)0x20000000; While(1) { While((AT91C_BASE_SYS->DBGU_CSR & 0x01)==0); Temp=AT91C_BASE_SYS->DBGU_RHR; Switch(Temp) { Case „C‟: Num=1; Break; Case ack: Sendlen=sendlen+128; Num++; Break; Case nak: Break; Case can: Return; Break; Default: Break; } //组包 If (sendlen>=len) { AT91C_BASE_SYS->DBGU_THR=eot; Return; } Arr[0]=soh; Arr[1]=num; Arr[2]=0xff-num; For(i=0;i<128;i++) { Arr[i+3]=sp[sendlen+i]; } Crc= crc16_ccitt(&arr[3],128); Arr[131]=(crc>>8) & 0xff; Arr[132]=(crc & 0xff); //send For(i=0;i<133;i++) { AT91C_BASE_SYS->DBGU_THR=arr[i]; While((AT91C_BASE_SYS->DBGU_CSR & 0x02)==0); } } } 12

数据流

数据流(data stream)最初是通信领域使用的概念,代表传输中所使用的信息的数字编码信号序列。然而,我们所提到的数据流概念与此不同。这个概念最初在1998年由Henzinger在文献87中提出,他将数据流定义为“只能以事先规定好的顺序被读取一次的数据的一个序列

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo8.com 版权所有 湘ICP备2023022238号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务