Ymodem协议说明

1、帧类型及符号说明

1.1、协议中用到的帧类型:
起始帧(发送方给接收方的第一帧数据)
数据帧(发送方给接收方的有效数据)
结束帧(发送方给接收方的最后一帧数据)

1.2、符号含义:
SOH:此ASCII码代表的16进制数为0x01(代表数据帧有128字节)
STX:此ASCII码代表的16进制数为0x02(代表数据帧有1024字节)
EOT:此ASCII码代表的16进制数为0x04(代表结束传输)
ACK:此ASCII码代表的16进制数为0x06(代表正确接收后的回应)
NACK:此ASCII码代表的16进制数为0x15(代表错误接收后的回应)
CAN:此ASCII码代表的16进制数为0x18(代表传输终止)
C:此ASCII码代表的16进制数为0x43(代表接收方请求发送方发送数据)

2、起始帧(接收方发起传输请求后由发送方发送的第一帧数据),帧结构如下:
在这里插入图片描述
起始帧各字节含义说明:
帧头SOH:表示这个帧中包含128个字节的数据,(此帧总长度=1个帧头+1个帧序+1个帧序反码+128个数据+1个CRC_H+1个CRC_L=133)
帧序00:表示帧序号,起始帧为0x00,即代表第一帧
帧序反码FF:是帧序号的取反,0x00的反码为0xFF
文件名:例如foo.c,其每个字符的ASCII码所对应的十六进制数为:0x66 0x6F 0x6F 0x2E 0x63。此文件名在起始帧中的存放格式为0x66 0x6F 0x6F 0x2E 0x63 0x00。注意:必须在文件名的最后,加一个0x00字节,0x00表示文件名结束
文件大小:假如上面的foo.c文件大小为1024字节,转换成16进制为0x400。此文件大小它在起始帧中存放格式为0x34 0x30 0x30 0x00,即字符串“400”的ASCII码再加一个字节的0x00,注意:必须在文件大小的最后加一个字节的0x00,0x00表示文件大小结束
NULL:数据部分大小为128字节,除去文件名与文件大小占用的空间外,剩余的x Bytes全部用0x00填充
CRC_H和CRC_L分别表示16位CRC校验码的高8位与低8位,校验只针对数据字节。

3、数据帧
在这里插入图片描述
数据帧各字节含义说明:
帧头STX:表示这帧数据的数据段有1024字节
帧头SOH:表示这帧数据的数据段有128字节
帧序num:第一帧数据帧的帧序号为0x01,第二帧数据帧的帧序号为0x02,
帧序反码~num:第一帧帧序反码为0Xfe,第二帧数据帧的帧序反码为0Xfd,
……以此类推。
CRC_H和CRC_L分别表示16位CRC校验码的高8位与低8位,校验只针对数据字节。

注:如果文件的最后一帧数据在128到1024字节之间,则使用STX作为帧头,数据字段的剩余空间全部用0x1A填充,如下结构:
STX num ~num data[ ] 0x1A 0x1A …… 0x1A CRC_H CRC_L

注:如果文件的最后一帧数据小于128字节,则使用SOH作为帧头,数据字段的剩余空间全部用0x1A填充,如下结构:
SOH num ~num data[ ] 0x1A 0x1A …… 0x1A CRC_H CRC_L

4、结束帧(发送方发送的最后一帧数据)
在这里插入图片描述
结束帧各字节含义说明:
SOH:代表此帧有128字节数据
帧序:固定为0x00
帧序反码:固定为0Xff
数据:全部为0x00
CRC_H:0x00
CRC_L:0x00

5、传输流程
文件的传输分为如下几个阶段:
5.1、接收方发起传输请求:接收方不断给发送方发送字符C,以期待收到发送方的数据回复。如下所示:
接收方发送‘C’------>发送方
……
接收方发送‘C’------>发送方

5.2、起始帧的发送及确认:发送方在上一步中接收到接收方发来的C字符,就开始发送起始帧数据。起始帧发送完后,发送方等待接收方应答ACK,发送方收到ACK后,等待接收方发送字符‘C’,发送方接收到‘C’之后开始正式传输文件内容。如下所示:
5.2.1、发送方发送起始帧------>接收方
5.2.2、接收方发送‘ACK’------>发送方
5.2.3、接收方发送‘C’------>发送方

5.3、文件内容的传输及确认:发送方每发一个文件数据帧,就会期待接收方应答一个ACK,接收到应答后,会发送下一个文件数据帧。如下所示:
5.3.1、发送方发送数据帧1------>接收方
5.3.2、接收方发送‘ACK’------>发送方
5.3.3、发送方发送数据帧2------>接收方
5.3.4、接收方发送‘ACK’------>发送方

5.4、传输过程中的异常处理
若发送方发完数据帧后,收到了接收方的NACK应答,则重发此帧。直到收到ACK应答或者发送超时后退出。如下所示:
5.4.1、发送方发送数据帧N------>接收方
5.4.2、接收方发送‘NACK’------>发送方
5.4.3、发送方发送数据帧N------>接收方
5.4.4、接收方发送‘ACK’------>发送方
5.4.5、发送方发送数据帧N+1------>接收方
5.4.6、接收方发送‘ACK’------>发送方
……
5.5、若发送方发完数据帧后,接收到了接收方的CAN应答,则停止数据帧的发送,结束传输。如下所示:
……
5.5.1、发送方发送数据帧N------>接收方
5.5.2、接收方发送‘ACK’------>发送方
5.5.3、发送方发送数据帧N+1------>接收方
5.5.4、接收方发送‘CAN’------>发送方
5.5.5、终止传输

5.6、数据传输结束
若发送方已将数据帧全部发送完毕,则发送‘EOT’来等待接收方的‘NACK’应答,当发送方接收到‘NACK’后,会再次发送‘EOT’,来等待接收方的‘C’应答后发送结束帧,发送结束帧后收到接收方的‘ACK’则表示本次传输完成。如下所示:
5.6.1、发送方发‘EOT’------>接收方
5.6.2、接收方发送‘NACK’------>发送方
5.6.3、发送方发‘EOT’------>接收方
5.6.4、接收方发送‘C’------>发送方
5.6.5、发送方发结束帧------>接收方
5.6.6、接收方发送‘ACK’------>发送方
发送方在接收到ACK后,传输结束

6、实例说明
假设文件名为foo.c,文件大小为4196字节(十六进制为0x1064)的文件作为输出对象,传输过程如下:
6.1、‘C’(接收方发送C来请求发送方发送起始帧)
6.2、‘SOH’ 00 FF 66 6F 6F 2E 63 00 31 00 36 34 00 NUL[117] CRC_H CRC_L(起始帧)
6.3、‘ACK’(接收方的应答)
6.4、‘C’(接收方发送C来请求数据帧)
6.5、‘STX’ 01 FE data[1024] CRC_H CRC_L(数据帧1)
6.6、‘ACK’(接收方的应答)
6.7、‘STX’ 02 FD data[1024] CRC_H CRC_L(数据帧2)
6.8、‘ACK’(接收方的应答)
6.9、‘STX’ 03 FC data[1024] CRC_H CRC_L(数据帧3)
6.10、‘NACK’(接收方的错误应答)
6.11、‘STX’ 03 FC data[1024] CRC_H CRC_L(数据帧3)
6.12、‘ACK’(接收方的应答)
6.13、‘STX’ 04 FB data[1024] CRC_H CRC_L(数据帧4)
6.14、‘ACK’(接收方的应答)
6.15、‘SOH’ 05 FA data[100] 0X1A[28] CRC_H CRC_L(数据帧5)
6.16、‘ACK’(接收方的应答)
6.17、‘EOT’(发收方发结束命令)
6.18、‘NACK’(接收方应答结束命令)
6.19、‘EOT’(发收方再次发结束命令)
6.20、‘C’(接收方应答,请求接收帧)
6.21、SOH 00 FF NUL[128] CRC_H CRC_L(结束帧)
6.22、‘ACK’(接收方应答结束命令)

7、CRC16校验代码

/**

  • @brief Update CRC16 for input byte
  • @param CRC input value
  • @param input byte
  • @retval None
    */
    uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
    {
    uint32_t crc = crcIn;
    uint32_t in = byte|0x100;
    do
    {
    crc <<= 1;
    in <<= 1;
    if(in&0x100)
    ++crc;
    if(crc&0x10000)
    crc ^= 0x1021;
    }
    while(!(in&0x10000));
    return crc&0xffffu;
    }

/**

  • @brief Cal CRC16 for YModem Packet
  • @param data
  • @param length
  • @retval None
    /
    uint16_t Cal_CRC16(const uint8_t
    data, uint32_t size)
    {
    uint32_t crc = 0;
    const uint8_t* dataEnd = data+size;
    while(data<dataEnd)
    crc = UpdateCRC16(crc,*data++);

crc = UpdateCRC16(crc,0);
crc = UpdateCRC16(crc,0);
return crc&0xffffu;
}

通过Ymodem协议,已经成功实现单片机的程序升级。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wxd82331

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

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

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

打赏作者

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

抵扣说明:

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

余额充值