一.关于ymodem协议的配置总结

一.对ymodem协议的基础通信结构解读:
(1)Ymodem 有两种帧格式,主要区别是信息块长度不一样。
在这里插入图片描述

(2)帧头表示两种数据帧长度,主要是信息块长度不同。
在这里插入图片描述

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

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

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

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

(7)Ymodem起始帧并不直接传输文件内容,而是先将文件名和文件大小置于数据帧中传输;起始帧是以SOH 133字节长度帧传输,格式如下。
在这里插入图片描述

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

(8)Ymodem数据帧传输,在信息块填充有效数据。
在这里插入图片描述

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

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

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

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

(9)Ymodem的结束帧采用SOH 133字节长度帧传输,该帧不携带数据(空包),即数据区、校验都以0x00填充。
在这里插入图片描述
(10)通信中的命令
在这里插入图片描述
二.文件内容。


//ymodem的命令的定义
#define SOH                     (0x01)  /* start of 128-byte data packet */
#define STX                     (0x02)  /* start of 1024-byte data packet */
#define EOT                     (0x04)  /* end of transmission */
#define ACK                     (0x06)  /* acknowledge */
#define NAK                     (0x15)  /* negative acknowledge */
#define CA                      (0x18)  /* two of these in succession aborts transfer */
#define CRC16                   (0x43)  /* 'C' == 0x43, request 16-bit CRC */

#define ABORT1                  (0x41)  /* 'A' == 0x41, abort by user */
#define ABORT2                  (0x61)  /* 'a' == 0x61, abort by user */
#define ENTER                   (0xd)  /*  enter , do not jump to app , done in 2S*/

#define NAK_TIMEOUT             (0x400000)
#define MAX_ERRORS              (3)
//传输的数据包的大小
#define PACKET_SIZE             (128)
#define PACKET_1K_SIZE          (1024)
//包的数据序号,以及比较缓存序号,用于确保数据包的序号
#define PACKET_SEQNO_INDEX      (1)
#define PACKET_SEQNO_COMP_INDEX (2)
//数据中的文件头,以及文件信息的在帧中占位长度
#define PACKET_HEADER           (3)
#define PACKET_TRAILER          (2)
#define PACKET_OVERHEAD         (PACKET_HEADER + PACKET_TRAILER)


#define Size_512KByte 524288 //存储字节格式

typedef struct
{
   
   uint8_t  begin;                              //1:正在传输,0:不在传输 2:传输完成
   uint32_t file_exist;                         //0:传输的文件不存在, 1:传输的文件存在
   UART_HandleTypeDef YmodemUart_Handler;       //对应ymodem的串口通信的结构体初始化句柄 等效huart_x
}Ymodem_TypeDef;

uint32_t file_verison,file_crc;//定义文件版本号以及文件32CRC,
uint32_t file_exist;//STM32中是否有文件标志 0:文件不存在, 1:文件存在

//用于将str》》》int转换的宏定义
#define IS_AF(c)  ((c >= 'A') && (c <= 'F'))
#define IS_af(c)  ((c >= 'a') && (c <= 'f'))
#define IS_09(c)  ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c)  IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c)  IS_09(c)
#define CONVERTDEC(c)  (c - '0')


程序:ymodem初始化,配置

//首先是初始化ymodem用到串口传输的初始化
void Ymodem_Init(void)
{
   
    huart2.Instance=USART2;					    
  	huart2.Init.BaudRate=115200;				   
  	huart2.Init.WordLength=UART_WORDLENGTH_8B;   
  	huart2.Init.StopBits=UART_STOPBITS_1;	    
  	huart2.Init.Parity=UART_PARITY_NONE;		    
  	huart2.Init.HwFlowCtl=UART_HWCONTROL_NONE;   
  	huart2.Init.Mode=UART_MODE_TX_RX;		   
  	HAL_UART_Init(&huart2);				
  	HAL_NVIC_DisableIRQ(USART2_IRQn);	//在NVIC中断控制器中禁用该设备的中断。
}

/**
  * @brief  将字符串转换成数字
  * @param  inputstr: 待转换的字符串
  * @param  intnum: 转换得到的数字
  * @retval 1: 正确
  *         0: 错误
  */
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
{
   
  uint32_t i = 0, res = 0;
  uint32_t val = 0;

  if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
  {
   
    if (inputstr[2] == '\0')
    {
   
      return 0;
    }
    for (i = 2; i < 11; i++)
    {
   
      if (inputstr[i] == '\0')
      {
   
        *intnum = val;
        /* return 1; */
        res = 1;
        break;
      }
      if (ISVALIDHEX(inputstr[i]))
      {
   
        val = (val << 4) + CONVERTHEX(inputstr[i]);
      }
      else
      {
   
        /* return 0, Invalid input */
        res = 0;
        break;
      }
    }
    /* over 8 digit hex --invalid */
    if (i >= 11)
    {
   
      res = 0;
    }
  }
  else /* max 10-digit decimal input */
  {
   
    for (i = 0;i < 11;i++)
    {
   
      if (inputstr[i] == '\0')
      {
   
        *intnum = val;
        /* return 1 */
        res = 1;
        break;
      }
      else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
      {
   
        val = val << 10;
        *intnum = val;
        res = 1;
        break;
      }
      else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
      {
   
        val = val << 20;
        *intnum = val;
        res = 1;
        break;
      }
      else if (ISVALIDDEC(inputstr[i]))
      {
   
        val 
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值