Ymodem协议要点

1.写在前面

  在进行文件传输时,为使文件能被正确识别和传送,需要在两台计算机之间建立统一的传输协议,协议需要包括了文件的识别、传送的起止时间、错误的判断与纠正等内容。常用的文件传输协议有:

【1】ASCII:传输速度快最快,但只能传送文本文件。
【2】Xmodem:协议古老悠久,传输速度较慢,采用了CRC校验算法,传输的准确率可高达99.6%;每次传输信息块为128字节。
【3】Ymodem:Ymodem是Xmodem的改进版,每次传输信息块最大1024字节,速度比Xmodem快;同时还支持传输多个文件。
【4】Zmodem:Zmodem采用了串流式(streaming)传输方式,传输速度较快,而且还具有自动改变区段大小和断点续传、快速错误侦测等功能。Zmodem目前最流行的文件传输协议。

  Ymodem协议用于计算机间传输文件,同样适用于嵌入式领域,如MCU升级固件时,可以使用Ymodem协议传输固件文件,传输总线不限于USB、UART、CAN等。

2.Ymodem 帧格式

  Ymodem 有两种帧格式,主要区别是信息块长度不一样。

名称帧头包号包号反码信息块校验
简写SOH/STXPNXPNDATACRC
字节数1111024/1282

2.1 帧头

  帧头表示两种数据帧长度,主要是信息块长度不同。

帧头SOH(0x01)STX(0x02)
信息块长度128字节1024字节

2.2 包序号

  数据包序号只有1字节,因此计算范围是0~255;对于数据包大于255的,序号归零重复计算。

2.3 帧长度

【1】以SOH(0x01)开始的数据包,信息块是128字节,该类型帧总长度为133字节。

【2】以STX(0x02)开始的数据包,信息块是1024字节,该类型帧总长度为1029字节。

2.4 校验

  Ymodem采用的是CRC16校验算法,校验值为2字节,传输时CRC高八位在前,低八位在后;CRC计算数据为信息块数据,不包含帧头、包号、包号反码。

3.Ymodem握手信号

  握手信号由接收方发起,在发送方开始传输文件前,接收方需发送YMODEM_C (字符C,ASII码为0x43)命令,发送方收到后,开始传输起始帧。

4.Ymodem起始帧

  Ymodem起始帧并不直接传输文件内容,而是先将文件名和文件大小置于数据帧中传输;起始帧是以SOH 133字节长度帧传输,格式如下。

帧头包号包号反码文件名称文件大小填充区校验高位校验低位
SOH0x000xffFile name+0x00File size+0x00NULL(0x00)CRC-HCRC-L

  其中包号为固定为0;Filename为文件名称,文件名称后必须加0x00作为结束;Filesize为文件大小值,文件大小值后必须加0x00作为结束;余下未满128字节数据区域,则以0x00填充。

5.Ymodem数据帧

  Ymodem数据帧传输,在信息块填充有效数据。

帧头包号包号反码有效数据校验高位校验低位
SOH/STXPNXPNDATACRC-HCRC-L

  传输有效数据时主要考虑的是最后一包数据的是处理,SOH帧和STR帧有不同的处理。

【1】对于SOH帧,若余下数据小于128字节,则以0x1A填充,该帧长度仍为133字节。

【2】对于STX帧需考虑几种情况:

  ●余下数据等于1024字节,以1029长度帧发送;
  ●余下数据小于1024字节,但大于128字节,以1029字节帧长度发送,无效数据以0x1A填充。
  ●余下数据等于128字节,以133字节帧长度发送。
  ●余下数据小于128字节,以133字节帧长度发送,无效数据以0x1A填充。

6.Ymodem结束帧

  Ymodem的结束帧采用SOH 133字节长度帧传输,该帧不携带数据(空包),即数据区、校验都以0x00填充。

帧头包号包号反码数据区校验高位校验低位
SOH0x000xff0x000x000x00

7.Ymodem命令

命令命令码备注
YMODEM_SOH0x01133字节长度帧
YMODEM_STX0x021024字节长度帧
YMODEM_EOT0x04文件传输结束命令
YMODEM_ACK0x06接收正确应答命令
YMODEM_NAK0x15重传当前数据包请求命令
YMODEM_CAN0x18取消传输命令,连续发送5个该命令
YMODEM_C0x43字符C
Ymodem是一种常用于串行通信的文件传输协议,它是Xmodem协议的改进版。Ymodem具备更高的传输速度和更好的错误检测与纠正能力。 Ymodem协议基于C语言实现比较简单,可以通过串口通信库函数或者底层串口通信接口来实现。下面是一个简单的Ymodem发送文件的C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define PACKET_SIZE 1024 // Ymodem SOH(128 bytes) #define SOH 0x01 // Ymodem EOT #define EOT 0x04 // Ymodem ACK #define ACK 0x06 // Ymodem NAK #define NAK 0x15 // Ymodem CAN #define CAN 0x18 // 发送一个Ymodem数据包 void sendPacket(char *packet, int packetSize) { // TODO: 将数据包通过串口发送 } // 发送文件(以Ymodem方式) int sendFile(char *fileName) { // 打开文件 FILE *file = fopen(fileName, "rb"); if (file == NULL) { printf("无法打开文件"); return -1; } // 获取文件大小 fseek(file, 0, SEEK_END); int fileSize = ftell(file); fseek(file, 0, SEEK_SET); // 计算需要发送的数据包数量 int packetCount = fileSize / PACKET_SIZE; if (fileSize % PACKET_SIZE != 0) { packetCount++; } // 发送文件名和文件大小信息 char fileInfo[PACKET_SIZE]; sprintf(fileInfo, "%s%d", fileName, fileSize); sendPacket(fileInfo, PACKET_SIZE); // 逐个发送数据包 int packetNum = 0; char packet[PACKET_SIZE]; while (packetNum < packetCount) { // 读取文件内容 memset(packet, 0, PACKET_SIZE); fread(packet, 1, PACKET_SIZE, file); // 发送数据包 sendPacket(packet, PACKET_SIZE); packetNum++; // 等待接收方ACK,如果接收方收到正确的数据包,则返回ACK(0x06),否则返回NAK(0x15) char response = NAK; while (response != ACK) { // TODO: 接收接收方的响应数据 // response = ... // 如果收到CAN(0x18)字符则终止传输 if (response == CAN) { fclose(file); return -1; } } } // 发送结束标志 sendPacket(&EOT, 1); // 等待接收方发送ACK while (1) { // TODO: 接收接收方的响应数据 // response = ... if (response == ACK) { break; } } fclose(file); return 0; } int main() { char *fileName = "test.txt"; sendFile(fileName); return 0; } ``` 以上是一个简单的Ymodem发送文件的C语言实现,通过发送SOH(Start of Heading)、EOT(End of Transmission)、ACK(Acknowledge)和NAK(Negative Acknowledge)等控制字符来进行通信和数据传输控制。在实际应用中,还需要实现相应的接收方代码来接收和处理Ymodem协议的传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Acuity.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值