扫描关注一起学嵌入式,一起学习,一起成长
在不限于嵌入式的很多工业应用场合,文件传输是非常常见的需求。小到上位机与单片机之间的固件传输过程,大到互联网中从服务器下载文件,再大到地面站到卫星,甚至深空探测器之间的资料传输,比如珍贵的火星照片。
在之前关于单片机 Bootloader 的文章中,详细介绍了如何对设备的APP进行升级。在升级过程中,要将APP文件传输到单片机中,期间需要一个稳定可到的协议,保证传输的文件数据不会出错。
深入浅出讲解单片机的BootLoader(二)
文件传输的根本是协议的设计与实现。而设计一个稳定可靠高效的文件传输协议,是需要一些技巧和智慧的。
本篇文章将详细介绍一些传输协议,最终大家会发现其实它们的基本思想是一样的。
Xmodem协议族
说到文件传输协议,就必须要说 Xmodem,它是所有文件传输协议的鼻祖。
1978 年,一位 IBM 的工程师尝试使用调制解调器来进行文件数据传输,并使其有一定的纠错能力,从而创建了一套协议,命名为 Xmodem。
其基本思想是:发送大小为 128 字节的数据包,如果包成功接收,接收方会返回一个肯定应答信号(ACK);如果发现错误,则返回一个否定应答信号(NAK)并重新发送数据包。Xmodem最初使用奇偶校验作为查错控制的方法。
Xmodem的传输过程
Xmodem 的逻辑很简单,下图为 Xmodem 的文件传输过程示意。
文件数据的传输过程其实就是收发双方交互协商的过程。既然是协商就会有双方遵循的约定,即所谓的协议。
首先是控制字的定义:
01H
04H
06H
15H
18H
图中已经涉及到了 ACK、NAK 和 EOT,不再赘述。
关于 CAN 的作用是这样的:当接收方发送 CAN 表示无条件结束本次传输过程,发送方收到 CAN 后,无需发送 EOT 来确认,直接停止数据的发送。可以看到,Xmodem每一帧数据都有独立的数据校验,加之它对重传的支持,使得文件传输的正确性得以保障。一般来说,只要通过 Xmodem 传输成功的文件,数据上是不会出现差错的,也就不需要单独再进行额外的文件校验。但是实际上我们还是会对接收到的文件整体进行检查,比如通过文件自身的校验码,因为除了传输,差错还可能出现在其它方面,比如存储。以上所介绍的内容其实是 Xmodem 最原始的形态,在此基础上它又有所改进,甚至衍生出一套协议族。最直接的一个改进,就是将其数据包的校验和,改为了双字节的 CRC,实际上是换汤不换药,但是它的传输交互过程有一些变化,如图 Xmodem(CRC)的文件传输过程示意。可以看到,Xmodem 如果使用 CRC 的话,在传输之初接收者是使用字符 ’C’ 来进行握手的,而校验和方式下,则是NAK,即 0X15。Xmodem 的这一改进,并不是对原来校验和方式的取代,而是补充。也就是说,现行实际 Xmodem 发送者有可能是采用CRC的,也可能是校验和,或者是两者都支持。这样问题就来了:接收者是用 ’C’ 来握手,还是用 NAK 呢?它决定了数据包的校验方式。接收者一般是设备端,为了使其更加通用(不挑协议),通常我们会兼顾校验和与CRC两种方式,具体实现方法如图所示。除了 Xmodem(CRC),Xmodem 的改进还有 Xmodem-1K,顾名思义,它的数据包中分片数据长度为 1KB,目的是提高传输效率。Ymodem的传输过程
几经改进的 Xmodem,人们给了它一个新的名字,Ymodem。它更加完备而高效,文件传输过程示意如图可以看到,Ymodem 的传输过程略显复杂,它最显著的特性是增加了启始帧和结束帧,两者的定义如图数据包中分片数据长度为1KB,其格式定义与 Xmodem不同,如下图所示,它引入了一个新的控制字,即STX,它是数据包的开始字符,值为 0X02。所以,Ymodem中有两种不同长度的数据帧,以 SOH 开头的数据帧数据长度为 128 字节,以 STX 开头的数据帧数据长度为 1024 字节。其中启始帧描述了更多的文件信息,包括文件名与文件大小。这一点是比 Xmodem 要完善的。同时,我们注意到Ymodem 是只支持 CRC 校验的,这比 Xmodem 更标准更统一。Ymodem是现行Xmodem协议族中最流行的版本,在很多的 Bootloader、OTA 等嵌入式方案中都有所应用,比如 RT-Thread 中就用 Ymodem 来实现上位机向其 DFS(设备文件系统)的文件传输。正所谓改进之心永不死,人们对 Ymodem 也不乏改进,衍生出了 Ymodem-G 版本,它去掉了 CRC 校验,当然这样就不能保证文件传输的正确性了。我也不知道这样算是“改进”还是“改退”,也许它有特定的应用场景吧。关于Zmodem
前面介绍了 Xmodem 与 Ymodem,它们有一定的继承性,但是 Zmodem 与它们相比完全不是一个量级的东西,要复杂得多。它不是基于发送与应答的机制,而是类似流式传输的一种协议。关于 Zmodem 我也没有找到比较明确的协议资料,所以并没有深入去研究它。这里我作了一个实验,抓取 Zmodem 实际传输过程中的收发双方的原始串口数据,贴在下面,若有兴趣可以自行研究一下,文件传输收发双方原始串口数据(上发下收)说明:使用 Xshell 打开两个串口(这两个串口收发相连),使用其中一个串口通过 Zmodem 发送文件 aaaa.txt(此文件内容是123456789),另一个串口接收文件。此过程中,使用串口监控软件记录其原始数据,以待分析。“Xshell是什么?串口监控软件是哪个?”关于这些工具软件,振南专门安排了一章来进行集中讲解,请关注相应章节。AVRUBD的传输过程
严格来说,AVRUBD 并不能算是 Xmodem 协议族中的一员,它只是对 Xmodem 的应用,只不过有些改进,请看图,AVRUBD传输文件的过程:可以看到,AVRUBD 的主要改进点有:
增加了密码联机的机制;
- 数据包中的数据长度可配置,不再局限于128B 或 1KB,而可以更灵活地配置。
这些改进点都是为单片机烧录程序服务的:
防止随意烧录,相当于增加了权限控制;
- 考虑单片机实际内存容量和烧录效率,可以灵活配置数据长度。
送你面值100的优惠券,扫码注册或者阅读原文即可获取。
觉得文章不错,点击“分享”、“赞”、“在看” 呗!