博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ymodem协议-接收
阅读量:4584 次
发布时间:2019-06-09

本文共 7576 字,大约阅读时间需要 25 分钟。

网上很多关于Ymodem协议的,有部分是错误的,以下是经过本人亲自编写的程序,测试可用。目前单片机作为接受端,用于IAP升级,发送还没写。另外对于终止传送也还没写,正常情况接收是完全没问题的。

划重点:《重复发送1024字节直到收到EOT开头数据,网上的错误点就在这里,搞了我很久,网上说的是不够128凑齐发SOH包,其实不是,是凑齐1024发STX包直到发EOT。》

平台:stm32f101v8  超级终端 keil

 

传输起来,效果是这样的!一般很快 如下图 2秒就7K了

 

首先超级终端中Ymodem协议是这样的,定义单片机位接受者,超级终端为发送者:

SOH开头: 128字节的数据,总包大小128+5,SOH即0x01

STX开头: 1024字节的数据,总包大小1024+5 ,STX即0x02

EOT开头: 单个字节,传输完成,总包大小1 ,EOT即0x04

/*YModem standard CMD*/

#define YMODEM_SOH (0x01)
#define YMODEM_STX (0x02)
#define YMODEM_EOT (0x04)
#define YMODEM_ACK (0x06)
#define YMODEM_NAK (0x15)
#define YMODEM_CAN (0x18)
#define YMODEM_C (0x43)

以下为交流顺序:

接受者:发送大写字母C,等待数据

发送者:发送ASCII中的SOH也就是01,后面是包序号00,包序号反码FF,文件名YG06_V0_1.bin,NULL,文件大小11212 bytes ,补齐111字节至128字节,CRC CRC是数据段的16位CRC校验码。总共此包是128+5=133字节。SOH

我的第一个包收到如下: 01 00 FF "YG06_V0_1.bin"  NULL "11212" NULL[111] CRC CRC

接受者:发送大写字母ACK,发送大写字母C,等待数据

发送者:发送ASCII中的STX也就是02,后面是包序号01,包序号反码FE,1024字节数据,CRC CRC.总共此包是1024+5=1029字节。STX

我的第一个包收到如下: 02 01 FE DATA[1024] CRC CRC

接受者:ACK

发送者:STX包

接受者:ACK

发送者:STX包

.......

接受者:ACK

发送者:EOT

重复发送1024字节直到收到EOT开头数据,网上的错误点就在这里,搞了我很久,网上说的是不够128凑齐发SOH包,其实不是,是凑齐1024发STX包直到发EOT。

 

接受者:NAK ( 第一次收到EOT发NAK )

 

发送者:EOT

 

接受者:ACK C( 第二次收到EOT发ACK 和大写 C )

 

发送者:SOH 00 FF NUL[128] CRC CRC (发送128字节空包)

 

 

接受者:ACK ( 传输结束 )、

简明如下:

 发送端                                                                             接收端

 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
C
SOH 00 FF "YG06_V0_1.bin"  NULL "11212" NULL[111] CRC CRC>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
C
STX 01 FE data[1024] CRC CRC>>>>>>>>>>>>>>>>>>>>>>>>      
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
STX 02 FD data[1024] CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
STX 03 FC data[1024] CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
STX 04 FB data[1024] CRC CRC>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
STX xx xx data[972]  1A[52] CRC CRC>>>>>>>>>>>>>>>>>>    补1A凑齐1024字节
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
EOT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
NAK
EOT>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
C
SOH 00 FF NUL[128] CRC CRC >>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<    
ACK 结束
附上程序如下:
ymodem.h
#ifndef _YMODEM_H_#define _YMODEM_H_#include "stm32f10x.h"#define MAX_LEN_TO_FLASH (1026)#define MAX_CACHE_LEN (135)typedef struct{    u8 Data[MAX_CACHE_LEN];    u16 cnt;}Cache_t;typedef struct{    u8 Data[MAX_LEN_TO_FLASH];    u16 cnt;    u8 x;}WriteToFlash_t;//extern Cache_t Cache;extern WriteToFlash_t WriteToFlash;/*YModem standard CMD*/#define YMODEM_SOH (0x01)#define YMODEM_STX (0x02)#define YMODEM_EOT (0x04)#define YMODEM_ACK (0x06)#define YMODEM_NAK (0x15)#define YMODEM_CAN (0x18)#define YMODEM_C (0x43)/*Rcv_CMD define*/#define IS_NOT_FIRST_PACKET (0x00)#define IS_FIRST_PACKET (0x01)#define IS_NORMAL_FILE_128 (0X02)#define IS_NORMAL_FILE_1024 (0X03)#define IS_END_OF_TRANSMIT (0X04)extern s8 YmodemSendACK(u8 byte);extern void RcvFile(u8 PacketReturn,u8 * IsFileEnd,u16* systickmark);extern s8 YmodemRcvPacket(u8 *rcvbuf,u16 buflen,u8 *result);u16 YModemCRC(u8 * data,u16 len);#endif

ymodem.c

#include "ymodem.h"#include "base_conf.h"#include "uart_dma.h"#include "crypt.h"#include "sysflash.h"#include "main.h"Cache_t Cache;WriteToFlash_t WriteToFlash;static u8 EOT_Flag = 0;s8 YmodemSendACK(u8 byte){    UART_PutChar(UART_DEBUG,byte);    //Delay_ms(100);    return 0;}void RcvFile(u8 PacketReturn,u8 * IsFileEnd,u16 * systickmark){    static u8 i=0;    switch(PacketReturn)    {        case IS_FIRST_PACKET:        {            YmodemSendACK(YMODEM_ACK);            YmodemSendACK(YMODEM_C);            *systickmark = GetCurrentTime();            break;        }        case IS_NORMAL_FILE_128:        {      memcpy(&WriteToFlash.Data[i*128],Cache.Data,Cache.cnt);            WriteToFlash.cnt += 128;            i++;            if(i==7)//write flash            {                i=0;                Flash_Program_bytes(Page(WriteToFlash.x+APP_FLASH_OFFSET/1024),WriteToFlash.Data,WriteToFlash.cnt);                WriteToFlash.x++;            }            YmodemSendACK(YMODEM_ACK);            *systickmark = GetCurrentTime();            break;        }        case IS_NORMAL_FILE_1024:        {            Flash_Program_bytes((Page(WriteToFlash.x+APP_FLASH_OFFSET/1024)),WriteToFlash.Data,WriteToFlash.cnt);            WriteToFlash.x++;            memset(WriteToFlash.Data,0,WriteToFlash.cnt);            YmodemSendACK(YMODEM_ACK);            *systickmark = GetCurrentTime();            break ;        }        case IS_END_OF_TRANSMIT:        {            if(EOT_Flag==1)            {                //Flash_Program_bytes(Page(WriteToFlash.x+APP_FLASH_OFFSET/1024),WriteToFlash.Data,WriteToFlash.cnt);                YmodemSendACK(YMODEM_NAK);            }            if(EOT_Flag==2)            {                YmodemSendACK(YMODEM_ACK);                YmodemSendACK(YMODEM_C);                            }            if(EOT_Flag==3)            {                Delay_ms(10);                YmodemSendACK(YMODEM_ACK);                EOT_Flag=0;              *IsFileEnd =1;                            }            break;        }    }}s8 YmodemRcvPacket(u8 *rcvbuf,u16 buflen,u8 *result){            u16 crc;      u8 debug;      u8 debug1;                  switch(*(rcvbuf))        {            case YMODEM_EOT:            {                EOT_Flag++;                *result =IS_END_OF_TRANSMIT ;                break;            }            case YMODEM_SOH:            {                debug=((~(*(rcvbuf+1))));          debug1=((*(rcvbuf+2)));          if(debug!=debug1)return -1;                memset(Cache.Data,0,sizeof(Cache.Data));                Cache.cnt = 128;                memcpy(Cache.Data,(rcvbuf+3),Cache.cnt);                crc=*(rcvbuf+128+3)<<8 | *(rcvbuf+128+3+1);                if(YModemCRC(Cache.Data,Cache.cnt)!=crc)return -1;        if(*(rcvbuf+1)==0)                {                    if(strstr((const char *)(Cache.Data),"YG06_V0_1.bin")!=NULL)                    {
*result=IS_FIRST_PACKET;} else{ if(*result == IS_END_OF_TRANSMIT ) //end with some of file,NULL DATA { *result =IS_END_OF_TRANSMIT ;EOT_Flag++; } else {
return -1;}//not the end of transmit,wrong file name } } else { *result =IS_NORMAL_FILE_128 ; } break; } case YMODEM_STX: { debug=((~(*(rcvbuf+1)))); debug1=((*(rcvbuf+2))); if(debug!=debug1)return -1; WriteToFlash.cnt = 1024; memcpy(WriteToFlash.Data,(rcvbuf+3),WriteToFlash.cnt); crc=*(rcvbuf+1024+3)<<8 | *(rcvbuf+1024+3+1); if(YModemCRC(WriteToFlash.Data,WriteToFlash.cnt)!=crc)return -1; *result =IS_NORMAL_FILE_1024 ; break; } default: { break; } } return 0;}u16 YModemCRC(u8 * data,u16 len){ int crc =0; int i,j; for(i=0;i
<< 1; } } } return (crc&0xFFFF);}

 

转载于:https://www.cnblogs.com/ycpkbql/p/9117129.html

你可能感兴趣的文章
各个控件说明
查看>>
鼠标事件(jQuery)
查看>>
delete指针时coredump的分析之旅
查看>>
openoffice+pdf2swf+FlexPaper在线显示office和pdf
查看>>
24-React Components组件
查看>>
[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】
查看>>
[BZOJ - 2631] tree 【LCT】
查看>>
ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程...
查看>>
JS实现数组排序:升序和降序
查看>>
怎样写具体设计文档
查看>>
CAShapeLayer
查看>>
ACM_夏天到了,又到了出游的季节
查看>>
【转载】HTTP 错误 500.19 - Internal Server Error
查看>>
2015 Multi-University Training Contest 3 hdu 5325 Crazy Bobo
查看>>
SQL Server 存储图片
查看>>
php特级课---4、网站服务监控(常用网站服务监控软件有哪些)
查看>>
ubuntu14.04 boost 1.58.0 安裝
查看>>
漏洞基本概念
查看>>
直角三角形 (Standard IO)
查看>>
web 12
查看>>