ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Ymodem传输协议

2021-10-17 23:33:38  阅读:195  来源: 互联网

标签:协议 00 ACK 发送 传输 128 接收 Ymodem


作者:zzssdd2

E-mail:zzssdd2@foxmail.com

〇、前言

近段时间做的项目涉及到设备固件OTA升级相关工作,其中有用到Ymodem协议传输数据,故整理一下Ymodem协议的知识。一是为写上位机/下位机做准备,二是做个备忘便于以后用时查阅。

一、符号说明

协议中用到的符号及其对应的数值和含义说明

符号 数值 含义
SOH 0x01 128字节数据包
STX 0x02 1024字节数据包
EOT 0x04 结束传输
ACK 0x06 正确接收回应
NAK 0x15 错误接收回应
CAN 0x18 传输中止
C 0x43 请求数据

二、传输起始帧

接收方发起传输请求后由发送方发送的第一包数据

帧头 帧序 帧序反码 文件名 文件大小 NULL CRC-H CRC-L
SOH 00 FF n Bytes m Bytes x Bytes 1 Byte 1 Byte
  • SOH:表示这个数据帧中包含着128个字节的数据段
  • 00:表示数据帧序号,初始是0,依次递增(满255从0开始)
  • FF:是帧序号的取反(提供一种数据是否正确的判断依据)
  • 数据段(128byte):文件名 + 文件大小 + NULL
    • 文件名:例如文件名是foo.c,ACSII字符转换为HEX字符就是66 6F 6F 2E 63。它在数据帧中存放格式为66 6F 6F 2E 63 00 ,最后加一个00表示文件名字段结束。
    • 文件大小:假如上面的foo.c文件大小为1024字节,转化成16进制即0x400。它在数据帧中存放格式为34 30 30 00,即ASCII格式的400,最后加一个00表示文件大小字段结束
    • NULL:数据部分大小为128字节,除去文件名与文件大小占用的空间外,剩余的x Bytes全部用00填充
  • CRC-H和CRC-L分别表示16位CRC校验码的高8位与低8位,校验只针对数据段。

三、传输数据帧

文件内容数据包

帧头 帧序 帧序反码 数据 CRC-H CRC-L
STX/SOH num ~num 1024/128 Bytes 1 Byte 1 Byte
  • STX 表示这帧数据的数据段为1024字节,SOH 表示这帧数据的数据段为128字节

  • 第一包帧序为01,帧序反码为FE,第二包帧序为02,其反码为FD......以此类推

  • CRC-H和CRC-L分别表示16位CRC校验码的高8位与低8位,校验只针对数据段。

  • 如果文件最后一帧数据在128~1024之间,则使用STX的1024字节传输,但是剩余空间全部用0x1A填充,如下结构:

    -------------------------------------------------------
    | STX | num | ~num | data[ ] | 1A ...1A | CRCH | CRCL |
    -------------------------------------------------------
    
  • 如果文件最后一帧数据小于128字节,则选择SOH的128字节来传输,但是剩余空间全部用0x1A填充,如下结构:

    ------------------------------------------------------
    | SOH | num | ~num | data[ ] | 1A...1A | CRCH | CRCL |
    ------------------------------------------------------
    

四、传输结束帧

发送方发送的最后一包数据

帧头 帧序 帧序反码 数据 CRC-H CRC-L
SOH 00 FF NUL[128] 00 00
  • 结束帧同样以SOH开头,表示后面跟着128字节的数据,结束帧的帧序也认为是00 FF
  • 结束帧的128字节的数据部分不存放任何信息,即NUL[128]全部用00填充
  • 因为数据段全为00,故校验码也为00 00

五、传输流程

文件的传输分为如下几个阶段进行

  • 阶段1:发起传输请求

接收方给发送方不断地发送字符'C',以期望收到发送方的数据响应。

接收方->>发送方: Char 'C'
接收方->>发送方: Char 'C'
......
  • 阶段2:起始帧的发送及确认

发送方收到接收方发来'C'字符,开始发送起始帧数据。等待接收方响应ACK标记,发送方收到ACK标记后等待接收方发送字符'C'则开始正式传输文件内容。

发送方->>接收方: Start packet
接收方->>发送方: ACK
接收方->>发送方: C
  • 阶段3:文件内容的传输及确认

发送方每发一个文件内容数据包,就期待接收方响应一个ACK标记,以继续发送下一个包。

发送方->>接收方: Packet 1
接收方->>发送方: ACK
发送方->>接收方: Packet 2
接收方->>发送方: ACK
......
  • 传输过程中的异常处理

若发送方发完数据包后收到了接收方NAK标记的响应,则重发此包,直到收到ACK响应或者超时退出。

发送方->>接收方: Packet n
接收方->>发送方: NAK
发送方->>接收方: Packet n
接收方->>发送方: ACK
发送方->>接收方: Packet n+1
......

若发送方发完数据包后收到了接收方CAN标记的响应,则停止数据包发送,结束传输。

......
发送方->>接收方: Packet n
接收方->>发送方: ACK
发送方->>接收方: Packet n+1
接收方->>发送方: CAN
中止传输
  • 阶段4:数据传输结束

若发送方已将数据包全部发完,则发送EOT标记等待接收方的NAK响应,当发送方收到NAK后会再次发送EOT等待接收方的C标记来请求结束帧,发送结束帧后收到接收方的ACK标记则表示本次传输完成

发送方->>接收方: EOT
接收方->>发送方: NAK
发送方->>接收方: EOT
接收方->>发送方: C
发送方->>接收方: Over packet
接收方->>发送方: ACK
传输结束

六、实例说明

假设以foo.c,大小为4196Bytes(16进制为0x1064)的文件作为传输对象,则它的传输过程如下:

发送方 传输方向 接收方
<<<<<<<<<<<<<<<< C(请求起始帧)
SOH 00 FF 66 6F 6F 2E 63 00 31 30 36 34 00 NUL[117] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
<<<<<<<<<<<<<<<< C(请求数据帧)
STX 01 FE data[1024] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
STX 02 FD data[1024] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
STX 03 FC data[1024] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< NAK(接收错误请求重发)
STX 03 FC data[1024] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
STX 04 FB data[1024] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
SOH 05 FA data[100] 1A[28] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK
EOT >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< NAK(响应结束命令)
EOT >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< C(请求结束帧)
SOH 00 FF NUL[128] CRCH CRCL >>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<< ACK

七、CRC16校验

数据帧中校验码的计算方式——C语言

/******************************************************************************************
*	函	数: CRC16_Xmodem
*	描	述: 计算CRC16-Xmodem
*		    多项式x16+x12+x5+1(0x1021) | 初始值0x0000 | 低位在后,高位在前 | 结果与0x0000异或
*	输	入: pData : 数据指针
*			ulSize : 数据长度
*	输	出: CRC16检验码
******************************************************************************************/
uint16_t CRC16_Xmodem(uint8_t *pData, uint32_t ulSize)  
{  
	uint8_t i;
    uint16_t usCRC = 0x0000;  
    
    while (ulSize--)     
    {  
        usCRC ^= (*pData++ << 8);
        for(i = 0; i < 8; i++)  
        {  
            if(usCRC & 0x8000)  
            {
                usCRC = (CRCin << 1) ^ 0x1021;  
            }
            else
            {              
                usCRC = usCRC << 1;
            }
        }  
    }  
    
    return usCRC;  
}  

标签:协议,00,ACK,发送,传输,128,接收,Ymodem
来源: https://www.cnblogs.com/zzssdd2/p/15418778.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有