Xmodem协议详解以及源代码
xmodem通信协议

xmodem通信协议
Xmodem是一种简单且可靠的串行通信协议,用于在计算机之间传输文件。
它的工作原理是将文件划分为若干个固定长度的数据块,并通过串行线路逐块传输。
每个数据块都包含了一个数据包编号、数据内容和校验和。
传输过程中,发送方将一个数据块发送给接收方,接收方收到后进行校验和验证。
如果数据块包含错误,则接收方会发送一个确认帧给发送方,要求重新发送该数据块。
如果数据块无误,则接收方发送一个确认帧给发送方,表示接收成功。
发送方收到确认帧后,再发送下一个数据块。
传输完成后,发送方发送一个传输结束帧,表示文件传输完毕。
Xmodem协议主要有三个版本:
1. Xmodem: 最早的版本,使用起始位和奇偶校验位来检查数
据的完整性。
每个数据块包含数据、校验和和一个确认帧。
2. Xmodem-CRC: 在Xmodem的基础上引入了循环冗余校验(CRC),提高了错误检测的准确性。
3. Xmodem-1K: 改进版本,每个数据块的长度增加到1024字节,提高了传输速度。
Xmodem通信协议简单易用,广泛应用于早期的串口通信设备和计算机之间的文件传输。
然而,由于其低效的传输速度和简单的错误处理机制,现在已经被更先进的协议所替代,如Ymodem、Zmodem和Kermit等。
Xmodem协议详解以及源代码剖析

研究 Xmodem 协议必看的 11个问题Xmodem 协议作为串口数据传输主要的方式之一,恐怕只有做过 bootloader 的才有机会接触一下, 网上有关该协议的内容要么是英语要么讲解不详细。
笔者以前写 bootloader 时研究过 1k-Xmodem ,参考了不少相关资料。
这里和大家交流一下我对 Xmodem 的理解,多多指教!1. Xmodem 协议是什么?XMODEM协议是一种串口通信中广泛用到的异步文件传输协议。
分为标准Xmodem 和 1k-Xmodem 两种,前者以 128字节块的形式传输数据,后者字节块为 1k 即 1024字节,并且每个块都使用一个校验和过程来进行错误检测。
在校验过程中如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个确认字节 (ACK。
由于 Xmodem 需要对每个块都进行认可, 这将导致性能有所下降, 特别是延时比较长的场合, 这种协议显得效率更低。
除了 Xmodem ,还有 Ymodem , Zmodem 协议。
他们的协议内容和 Xmodem 类似,不同的是 Ymodem 允许批处理文件传输,效率更高; Zmodem 则是改进的了Xmodem ,它只需要对损坏的块进行重发,其它正确的块不需要发送确认字节。
减少了通信量。
2. Xmodem 协议相关控制字符SOH 0x01STX 0x02EOT 0x04ACK 0x06NAK 0x15CAN 0x18CTRLZ 0x1A3.标准 Xmodem 协议(每个数据包含有 128字节数据帧格式_______________________________________________________________| SOH | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和 ||_____|____________|___________________|__________|____________|4. 1k-Xmodem (每个数据包含有 1024字节数据帧格式_______________________________________________________________| STX | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和 ||_____|____________|___________________|__________|____________|5.数据包说明对于标准 Xmodem 协议来说,如果传送的文件不是 128的整数倍,那么最后一个数据包的有效内容肯定小于帧长,不足的部分需要用 CTRL- Z(0x1A来填充。
XMODEM协议

XMODEM协议XMODEM协议是一种简单而古老的串行通信协议,它用于在计算机之间进行文件传输。
XMODEM协议最初由Ward Christensen和Keith Petersen于1977年开发,它是第一个广泛使用的文件传输协议之一。
尽管XMODEM协议已经被更先进的协议所取代,但它的基本原理仍然对我们理解现代通信协议有所帮助。
XMODEM协议的工作原理非常简单。
发送方将文件分成128字节的数据块,每个数据块都会被编号,接收方在接收到数据块后会发送一个确认信号,如果发送方没有收到确认信号,它会重新发送数据块。
这种简单的确认和重传机制确保了数据的可靠传输。
XMODEM协议的简单性使得它在早期个人计算机上得到了广泛的应用。
然而,它也存在一些缺点。
首先,XMODEM协议的速度相对较慢,因为它在发送每个数据块后都需要等待确认信号。
其次,XMODEM协议没有进行错误检测和纠正,因此在传输过程中很容易出现数据损坏的情况。
为了解决XMODEM协议的缺点,后来出现了一些改进版本,比如YMODEM和ZMODEM。
这些改进版本在速度和可靠性上都有所提高,但它们仍然保留了XMODEM协议的基本原理。
这些改进版本在一定程度上延续了XMODEM协议的影响,但随着现代通信技术的发展,它们也逐渐被更先进的协议所取代。
尽管XMODEM协议已经不再是主流的文件传输协议,但它作为通信协议的基础原理仍然具有重要意义。
通过学习XMODEM协议,我们可以更好地理解通信协议的工作原理,从而更好地理解和应用现代通信技术。
总的来说,XMODEM协议作为早期的文件传输协议,虽然已经被更先进的协议所取代,但它的简单原理和基本思想仍然对我们有所启发。
通过了解XMODEM协议,我们可以更好地理解通信协议的发展历程,从而更好地应用现代通信技术。
因此,即使XMODEM协议已经不再被广泛使用,但它的影响仍然存在,它对我们理解通信协议的发展和应用具有重要意义。
Xmodem、Ymodem协议总结

Xmodem、Ymodem协议总结写在前⾯: 本⽂包含如下内容: ⼀、 ⼆、 三、 四、 (4-1) (4-2) 五、 (5-1) (5-2) (5-3) (5-4)⼀、⽂件传输简介 ⽂件传输是数据交换的主要形式。
在进⾏⽂件传输时,为使⽂件能被正确识别和传送,我们需要在两台计算机之间建⽴统⼀的传输协议。
这个协议包括了⽂件的识别、传送的起⽌时间、错误的判断与纠正等内容。
Xmodem、Ymodem和Zmodem协议是最常⽤的三种通信协议。
⼆、传输协议 在SecureCRT下的传输协议有ASCII、Xmodem、Ymodem、Zmodem等。
如下图所⽰,在开发中,可以使⽤SecureCRT软件进⾏⽂件传输。
三、协议特点 (1)Xmodem协议是最早的,传输128字节信息块。
(2)Ymodem是Xmodem的改进版协议,具有传输快速稳定的优点。
它可以⼀次传输1024字节的信息块,同时还⽀持传输多个⽂件。
平常所说的Ymodem协议是指的Ymodem-1K,除此还有Ymodem-g(没有CRC校验,不常⽤)。
YModem-1K⽤1024字节信息块传输取代标准的128字节传输,数据的发送会使⽤CRC校验,保证数据传输的正确性。
它每传输⼀个信息块数据时,就会等待接收端回应ACK信号,接收到回应后,才会继续传输下⼀个信息块,保证数据已经全部接收。
四、XModem协议解析 Xmodem协议传输有接收程序和发送程序完成,先由接收程序发送协商字符,协商校验⽅式,协商通过之后发送程序就开始发送数据包,接收程序接收到完整的⼀个数据包之后按照协商的⽅式对数据包进⾏校验。
校验通过之后发送确认字符,然后发送程序继续发送下⼀包;如果校验失败,则发送否认字符,发送程序重传此数据包。
定义: SOH 01H(modem数据头) EOT 04H(发送结束) ACK 06H(应答) NAK 15H(⾮应答) CAN 18H(取消发送) Xmodem数据包,包含⼀个标题开始字符,⼀个单字节包序号,⼀个包序号的补码,128字节数据和⼀个双字节的CRC校验。
xmodem_串口_传输_协议

Xmodem协议)V1.1 - Dec 8, 2005中文版19, Innovation First Road • Science Park • Hsin-Chu • Taiwan 300 • R.O.C.Tel: 886-3-578-6005 Fax: 886-3-578-4418 E-mail: mcu@版权声明凌阳科技股份有限公司保留对此文件修改之权利且不另行通知。
凌阳科技股份有限公司所提供之信息相信为正确且可靠之信息,但并不保证本文件中绝无错误。
请于向凌阳科技股份有限公司提出订单前,自行确定所使用之相关技术文件及规格为最新之版本。
若因贵公司使用本公司之文件或产品,而涉及第三人之专利或著作权等智能财产权之应用及配合时,则应由贵公司负责取得同意及授权,本公司仅单纯贩售产品,上述关于同意及授权,非属本公司应为保证之责任。
又未经凌阳科技股份有限公司之正式书面许可,本公司之所有产品不得使用于医疗器材,维持生命系统及飞航等相关设备。
页1系统概要 (5)1.1系统说明 (5)1.2Xmodem简介 (5)1.3Xmodem协议 (5)1.3.1相关说明 (5)1.3.2协议简介 (5)1.3.3校验和信息包 (6)1.3.4CRC校验信息包 (7)1.4系统组成 (9)2软件说明 (10)2.1软件说明 (10)2.2档案构成 (10)2.3子程序说明 (10)3程序范例 (13)3.1DEMO程序 (13)3.2文件传输 (15)4MCU使用资源 (19)4.1MCU硬件使用资源说明 (19)5参考文献 (26)版本日期编写及修订者编写及修订说明1.0 2004/01/13初版1.1 2005/12/08错误校正Sender Flow ReceiverNAK <---OKSOH 0x05 0xFA Data[0-127]Chksum---> Packet<---ACKOKEOT --->PacketACK get garbaged <--- ACKOKEOT --->PacketACKFinished <---1.3.4 CRC校验信息包1、CRC校验信息包<SOH><blk #><255-blk #><--128 data bytes--><CRC hi><CRC lo>其中:<SOH> = 01 hex信息包序号,从 01开始以发送一包将加1,加到FF hex将循环。
xmodem协议介绍及VxWorks下的应用

/*最大重试次数*/
#define MAX_RETRY
10
/*最大包序列宏定义*/
#define MAX_SEQNO
255Biblioteka /*等待包头的时间 10S*/
#define WAIT_SOH_TIME 10
/*发送 C 字符的次数*/
#define SEND_C_TIMES
3
/*校验和方式*/
#define CHECK_CRC
发送端发现最后一个数据包不足 128 字节时,填充 CTRL+Z (0x1a)。发送端发送完毕后
发送 EOT 结束文件传输,或者发现接收端一直不响应或对同一数据包响应 NAK 超过规定次
数(一般 10 次)时发送 CAN 取消传输。接收端接收到 EOT 或 CAN 时结束传输流程。
下面以校验和 checksum 的数据包传输流程说明 xmodem 协议的原理。接收端启动连接后,
xmodem 协议介绍及 VxWorks 下的应用
最初,XMODEM 协议是一种基于调制解调器直接拨号通讯的文件传输协议,用来支持两台 计 算 机 之 间 的 文 件 传 输 。由于其简单可靠、实现方便的特性,现在已经广泛应用于嵌入式设备 中。实现 xmodem 只需要微处理器带有串口控制器就行了,一般的 8 位单片机也能进行文件 传输。
/*CRC 计算*/ U16 CRC16_CCITT (U8 *ptr, S32 count) {
U16 usCrc; U8 * pTmp; U16 i;
usCrc = 0; pTmp = ptr; while (--count >= 0) {
usCrc = usCrc ^ ((U16)( *pTmp++ ) << 8); for ( i = 0; i < 8; ++i) {
研究Xmodem协议必看的11个问题

研究Xmodem协议必看的11个问题Xmodem协议作为串口数据传输主要的方式之一,恐怕只有做过bootloader的才有机会接触一下,网上有关该协议的内容要么是英语要么讲解不详细。
笔者以前写bootloader时研究过1k-Xmodem,参考了不少相关资料。
这里和大家交流一下我对Xmodem的理解,多多指教!1.Xmodem协议是什么?XMODEM协议是一种串口通信中广泛用到的异步文件传输协议。
分为标准Xmodem 和1k-Xmodem两种,前者以128字节块的形式传输数据,后者字节块为1k即1024字节,并且每个块都使用一个校验和过程来进行错误检测。
在校验过程中如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个确认字节(ACK)。
由于Xmodem需要对每个块都进行认可,这将导致性能有所下降,特别是延时比较长的场合,这种协议显得效率更低。
除了Xmodem,还有Ymodem,Zmodem协议。
他们的协议内容和Xmodem类似,不同的是Ymodem允许批处理文件传输,效率更高;Zmodem则是改进的了Xmodem,它只需要对损坏的块进行重发,其它正确的块不需要发送确认字节。
减少了通信量。
2.Xmodem协议相关控制字符SOH 0x01STX 0x02EOT 0x04ACK 0x06NAK 0x15CAN 0x18CTRLZ 0x1A3.标准Xmodem协议(每个数据包含有128字节数据)帧格式_______________________________________________________________| | | | | || SOH | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和 ||_____|____________|___________________|__________|____________|4.1k-Xmodem(每个数据包含有1024字节数据)帧格式_______________________________________________________________| | | | | || STX | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和 ||_____|____________|___________________|__________|____________|5.数据包说明对于标准Xmodem协议来说,如果传送的文件不是128的整数倍,那么最后一个数据包的有效内容肯定小于帧长,不足的部分需要用CTRL-Z(0x1A)来填充。
Xmodem协议详解以及源代码

研究Xmodem协议必看的11个问题原文地址:/s/blog_4db10c6c0100av57.html~type=v5 _one&label=rela_prevarticleXmodem协议作为串口数据传输主要的方式之一,恐怕只有做过bootloader的才有机会接触一下,网上有关该协议的内容要么是英语要么讲解不详细。
笔者以前写bootloader时研究过1k-Xmodem,参考了不少相关资料。
这里和大家交流一下我对Xmodem的理解,多多指教!1.Xmodem协议是什么?XMODEM协议是一种串口通信中广泛用到的异步文件传输协议。
分为标准X modem和1k-Xmodem两种,前者以128字节块的形式传输数据,后者字节块为1 k即1024字节,并且每个块都使用一个校验和过程来进行错误检测。
在校验过程中如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个确认字节 (ACK)。
由于Xmodem需要对每个块都进行认可,这将导致性能有所下降,特别是延时比较长的场合,这种协议显得效率更低。
除了Xmodem,还有Ymodem,Zmodem协议。
他们的协议内容和Xmodem类似,不同的是Ymodem允许批处理文件传输,效率更高;Zmodem则是改进的了X modem,它只需要对损坏的块进行重发,其它正确的块不需要发送确认字节。
减少了通信量。
2.Xmodem协议相关控制字符SOH 0x01STX 0x02EOT 0x04ACK 0x06NAK 0x15CAN 0x18CTRLZ 0x1A3.标准Xmodem协议(每个数据包含有128字节数据)帧格式_______________________________________________________________ | | || | || SOH | 信息包序号| 信息包序号的补码 | 数据区段| 校验和||_____|____________|___________________|__________|____________| 4.1k-Xmodem(每个数据包含有1024字节数据)帧格式_______________________________________________________________ | | || | || STX | 信息包序号| 信息包序号的补码 | 数据区段| 校验和||_____|____________|___________________|__________|____________| 5.数据包说明对于标准Xmodem协议来说,如果传送的文件不是128的整数倍,那么最后一个数据包的有效内容肯定小于帧长,不足的部分需要用CTRL- Z(0x1A)来填充。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
研究Xmodem协议必看的11个问题Xmodem协议作为串口数据传输主要的方式之一,恐怕只有做过bootloader的才有机会接触一下,网上有关该协议的内容要么是英语要么讲解不详细。
笔者以前写bootloader时研究过1k-Xmodem,参考了不少相关资料。
这里和大家交流一下我对Xmodem的理解,多多指教!1.Xmodem协议是什么?XMODEM协议是一种串口通信中广泛用到的异步文件传输协议。
分为标准Xmodem和1k-Xmodem两种,前者以128字节块的形式传输数据,后者字节块为1k即1024字节,并且每个块都使用一个校验和过程来进行错误检测。
在校验过程中如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个确认字节 (ACK)。
由于Xmodem需要对每个块都进行认可,这将导致性能有所下降,特别是延时比较长的场合,这种协议显得效率更低。
除了Xmodem,还有Ymodem,Zmodem协议。
他们的协议内容和Xmodem类似,不同的是Ymodem允许批处理文件传输,效率更高;Zmodem则是改进的了Xmodem,它只需要对损坏的块进行重发,其它正确的块不需要发送确认字节。
减少了通信量。
2.Xmodem协议相关控制字符SOH 0x01STX 0x02EOT 0x04ACK 0x06NAK 0x15CAN 0x18CTRLZ 0x1A3.标准Xmodem协议(每个数据包含有128字节数据)帧格式_______________________________________________________________| SOH | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和||_____|____________|___________________|__________|____________|4.1k-Xmodem(每个数据包含有1024字节数据)帧格式_______________________________________________________________| STX | 信息包序号 | 信息包序号的补码 | 数据区段 | 校验和||_____|____________|___________________|__________|____________|5.数据包说明对于标准Xmodem协议来说,如果传送的文件不是128的整数倍,那么最后一个数据包的有效内容肯定小于帧长,不足的部分需要用CTRL- Z(0x1A)来填充。
这里可能有人会问,如果我传送的是bootloader工程生成的.bin文件,mcu收到后遇到0x1A字符会怎么处理?其实如果传送的是文本文件,那么接收方对于接收的内容是很容易识别的,因为CTRL-Z不是前128个ascii码,不是通用可见字符,如果是二进制文件,mcu其实也不会把它当作代码来执行。
哪怕是excel文件等,由于其内部会有些结构表示各个字段长度等,所以不会读取多余的填充字符。
否则 Xmodem太弱了。
对于1k-Xmodem,同上理。
6.如何启动传输?传输由接收方启动,方法是向发送方发送"C"或者NAK(注意哦,这里提到的NAK是用来启动传输的。
以下我们会看到NAK还可以用来对数据产生重传的机制)。
接收方发送NAK信号表示接收方打算用累加和校验;发送字符"C"则表示接收方想打算使用CRC校验(具体校验规则下文Xmodem源码,源码胜于雄辩)。
7.传输过程当接收方发送的第一个"C"或者NAK到达发送方,发送方认为可以发送第一个数据包,传输已经启动。
发送方接着应该将数据以每次128字节的数据加上包头,包号,包号补码,末尾加上校验和,打包成帧格式传送。
发送方发了第一包后就等待接收方的确认字节ACK,收到接收方传来的ACK确认,就认为数据包被接收方正确接收,并且接收方要求发送方继续发送下一个包;如果发送方收到接收方传来的NAK(这里,NAK用来告诉发送方重传,不是用来启动传输)字节,则表示接收方请求重发刚才的数据包;如果发送方收到接收方传来的CAN字节,则表示接收方请求无条件停止传输。
8.如何结束传输?如果发送方正常传输完全部数据,需要结束传输,正常结束需要发送方发送EOT 字节通知接收方。
接收方回以ACK进行确认。
当然接收方也可强制停止传输,当接收方发送CAN 字节给发送方,表示接收方想无条件停止传输,发送方收到CAN后,不需要再发送 EOT确认(因为接收方已经不想理它了,呵呵)。
9.特殊处理虽然数据包是以 SOH 来标志一个信息包的起始的,但在 SOH 位置上如果出现EOT则表示数据传输结束,再也没有数据传过来。
接收方首先应确认数据包序号的完整性,通过对数据包序号取补,然后和数据包序号的补码异或,结果为0表示正确,结果不为0则发送NAK请求重传。
接收方确认数据包序号正确后,然后检查是否期望的序号。
如果不是期望得到的数据包序号,说明发生严重错误,应该发送一个 CAN 来中止传输。
如果接收到的数据包的包序号和前一包相同,那么接收方会忽略这个重复包,向发送方发出 ACK ,准备接收下一个包。
接收方确认了信息包序号的完整性和是正确期望的后,只对 128 字节的数据区段进行算术和校验,结果与帧中最后一个字节(算术校验和)比较,相同发送 ACK,不同发送 NAK。
10.校验和的说明Xmodem协议支持2种校验和,它们是累加和与CRC校验。
当接收方一开始启动传输时发送的是NAK,表示它希望以累加和方式校验。
当接收方一开始启动传输时发送的是字符“C”,表示它希望以CRC方式校验。
可能有人会问,接收方想怎么校验发送方都得配合吗,难道发送方必须都支持累加和校验和CRC校验?事实上Xmodem要求支持CRC的就必须同时支持累加和,如果发送方只支持累加和,而接收方用字符“C”来启动,那么发送方只要不管它,当接收方继续发送“C”,三次后都没收到应答,就自动会改为发送 NAK,因为它已经明白发送方可能不支持CRC校验,现在接收方改为累加和校验和发送方通讯。
发送方收到NAK就赶紧发送数据包响应。
11.Xmodem协议代码看了以上说明,再参考代码,应该很容易会理解代码编写者的思路。
XModem 源码#include "crc16.h"#define SOH 0x01#define STX 0x02#define EOT 0x04#define ACK 0x06#define NAK 0x15#define CAN 0x18#define CTRLZ 0x1A#define DLY_1S 1000#define MAXRETRANS 25static int last_error = 0;#include "string.h"void port_outbyte(unsigned char trychar){unsigned char buf[2];buf[0] = trychar;lowLevel_write(buf,1);}unsigned char port_inbyte(unsigned int time_out) {unsigned char ch; int i;last_error = 0;if(lowLevel_read(&ch,1) == 1) return ch;last_error = 1;return ch;}static int check(int crc, const unsigned char *buf, int sz) {if (crc){unsigned short crc = crc16_ccitt(buf, sz);unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];if (crc == tcrc) return 1;}else{int i;unsigned char cks = 0;for (i = 0; i < sz; ++i){cks += buf[i];}if (cks == buf[sz]) return 1;}return 0;}static void flushinput(void){//while (port_inbyte(((DLY_1S)*3)>>1) >= 0) ; }int xmodemReceive(unsigned char *dest, int destsz) {unsigned char xbuff[1030];unsigned char *p;int bufsz, crc = 0;unsigned char trychar = 'C';unsigned char packetno = 1;int i, c, len = 0;int retry, retrans = MAXRETRANS;for(;;){for( retry = 0; retry < 16; ++retry){if (trychar)port_outbyte(trychar);c = port_inbyte((DLY_1S)<<1);if (last_error == 0){switch (c){case SOH:bufsz = 128;goto start_recv;case STX:bufsz = 1024;goto start_recv;case EOT:flushinput();port_outbyte(ACK);return len;case CAN:c = port_inbyte(DLY_1S);if (c == CAN){flushinput();port_outbyte(ACK);return -1;}break;default:break;}}}if (trychar == 'C'){trychar = NAK;continue;}flushinput();port_outbyte(CAN);port_outbyte(CAN);port_outbyte(CAN);return -2;start_recv:if (trychar == 'C')crc = 1;trychar = 0;p = xbuff;*p++ = c;for (i = 0; i < (bufsz+(crc?1:0)+3); ++i){c = port_inbyte(DLY_1S);if (last_error != 0)goto reject;*p++ = c;}if (xbuff[1] == (unsigned char)(~xbuff[2]) &&(xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1)&& check(crc, &xbuff[3], bufsz)){if (xbuff[1] == packetno){int count = destsz - len;if (count > bufsz)count = bufsz;if (count > 0){memcpy (&dest[len], &xbuff[3], count);len += count;}++packetno;retrans = MAXRETRANS+1;}if (--retrans <= 0){flushinput();port_outbyte(CAN);port_outbyte(CAN);port_outbyte(CAN);return -3;}port_outbyte(ACK);continue;}reject:flushinput();port_outbyte(NAK);}}int xmodemTransmit(unsigned char *src, int srcsz){unsigned char xbuff[1030];int bufsz, crc = -1;unsigned char packetno = 1;int i, c, len = 0;int retry;for(;;){for( retry = 0; retry < 16; ++retry){c = port_inbyte((DLY_1S)<<1);if (last_error == 0){switch (c){case 'C':crc = 1;goto start_trans;case NAK:crc = 0;goto start_trans;case CAN:c = port_inbyte(DLY_1S);if (c == CAN){port_outbyte(ACK);flushinput();return -1;}break;default:break;}}}port_outbyte(CAN);port_outbyte(CAN);port_outbyte(CAN);flushinput();return -2;for(;;){start_trans:xbuff[0] = SOH;bufsz = 128;xbuff[1] = packetno;xbuff[2] = ~packetno;c = srcsz - len;if (c > bufsz)c = bufsz;if (c >= 0){memset (&xbuff[3], 0, bufsz);if (c == 0){xbuff[3] = CTRLZ;}else{memcpy (&xbuff[3], &src[len], c);if (c < bufsz)xbuff[3+c] = CTRLZ;}if (crc){unsigned short ccrc = crc16_ccitt(&xbuff[3], bufsz);xbuff[bufsz+3] = (ccrc>>8) & 0xFF; xbuff[bufsz+4] = ccrc & 0xFF;}else{unsigned char ccks = 0;for (i = 3; i < bufsz+3; ++i){ccks += xbuff[i];}xbuff[bufsz+3] = ccks;}for (retry = 0; retry < MAXRETRANS; ++retry){for (i = 0; i < bufsz+4+(crc?1:0); ++i){port_outbyte(xbuff[i]);}c = port_inbyte(DLY_1S);if (last_error == 0 ){switch (c){case ACK:++packetno;len += bufsz;goto start_trans;case CAN:c = port_inbyte(DLY_1S);if ( c == CAN){port_outbyte(ACK);flushinput();return -1;}break;case NAK:default:break;}}}port_outbyte(CAN);port_outbyte(CAN);port_outbyte(CAN);flushinput();return -4;}else{for (retry = 0; retry < 10; ++retry){port_outbyte(EOT);c = port_inbyte((DLY_1S)<<1);if (c == ACK)break;}flushinput();return (c == ACK)?len:-5;}}}}。