ymodem协议c实现(转)
/****************************************Copyright (c)**************************************************
** Henan Star Hi-Tech CO.,LTD
** All rights reserved.
**
**----------------------------------------File Info-----------------------------------------------------
** 文件名称:
** 工程项目:
** 说 明:
**
** 作 者: 日 期:
** 建立版本:
**
**----------------------------------------modification--------------------------------------------------
** 作 者:
** 日 期:
** 版 本: 标 记:
** 说 明:
**
********************************************************************************************************/ #ifndef __XYMODEM_H_
#define __XYMODEM_H_ #define MODEM_MAX_RETRIES 50 //接收等待延时时间
#define MODEM_CRC_RETRIES 51 //>MODEM_MAX_RETRIES固定为CRC校验
#define MODEM_CAN_COUNT 3 //Wait for 3 times CAN before quiting
#define MODEM_EOT_COUNT 1 #define MODEM_SOH 0x01 //数据块起始字符
#define MODEM_STX 0x02
#define MODEM_EOT 0x04
#define MODEM_ACK 0x06
#define MODEM_NAK 0x15
#define MODEM_CAN 0x18
#define MODEM_C 0x43 typedef struct{
int modemtype;
int crc_mode;
int nxt_num; //下一数据块序号
int cur_num; //当块序号
int len;
int rec_err; //数据块接收状态
unsigned char buf[]; //数据
unsigned int filelen; //Ymodem可有带文件名称和长度
unsigned char filename[];
}modem_struct; #ifdef __cplusplus
extern "C"{
#endif int ymodem_init(modem_struct *mblock);
int modem_recvdata(modem_struct *mblock);
//int crc_16(unsigned char *buf, int len);
void modem_cancle(void);
#ifdef __cplusplus
}
#endif #endif
/****************************************Copyright (c)**************************************************
** Henan Star Hi-Tech CO.,LTD
** All rights reserved.
**
**----------------------------------------File Info-----------------------------------------------------
** 文件名称:
** 工程项目:
** 说 明:
**
** 作 者: 日 期:
** 建立版本:
**
**----------------------------------------modification--------------------------------------------------
** 作 者:
** 日 期:
** 版 本: 标 记:
** 说 明:
**
********************************************************************************************************/ #include "xymodem1.h"
#include "heads.h" unsigned int buf_filelen(unsigned char *ptr); /*****************************************************************************************
** 函数名称:
** 函数功能:
** 入口参数:
** 返 回 值:
** 编 写: 日 期: 版 本 号:
** 修改历史:
******************************************************************************************/
int ymodem_init(modem_struct *mblock)
{
int stat;
int max_tries = MODEM_MAX_RETRIES;
int crc_tries =MODEM_CRC_RETRIES;
unsigned char *bufptr = mblock->buf;
unsigned char *namptr = mblock->filename; mblock->nxt_num = ;
mblock->modemtype = ;
mblock->rec_err = ;
mblock->crc_mode = ; while (max_tries-- > )
{
stat = modem_recvdata(mblock);
if ( == stat) //接收成功
{
//file name
while (*bufptr != '\0')
{
*namptr++ = *bufptr++;
}
*namptr = '\0';
bufptr++;
while (*bufptr == ' ')
{
bufptr++;
}
//file length
mblock->filelen = buf_filelen(bufptr);
//other data;
Uart_SendByte(MODEM_ACK);
return ;
}
else if ( == stat) //取消传输
{
return ;
}
else if (- == stat)
{
if (mblock->cur_num == )
{
mblock->modemtype = ;
mblock->nxt_num = ;
return ;
}
}
else //超时或校验方式不对
{
if (crc_tries-- <= )
{
crc_tries = MODEM_CRC_RETRIES;
mblock->crc_mode = (mblock->crc_mode+) & ;
}
}
}
return -;
} /*****************************************************************************************
** 函数名称:
** 函数功能:
** 入口参数:
** 返 回 值:0:成功接收数据 -1:接收超时 -2:帧错误
-3:帧序号序号错误(严重错误) 1:消息结束 2:取消发送
** 编 写: 日 期: 版 本 号:
** 修改历史:
******************************************************************************************/
int modem_recvdata(modem_struct *mblock)
{
int stat, hd_found=, i;
int can_counter=, eot_counter=;
unsigned char *in_ptr = mblock->buf;
int cksum;
unsigned char ch, blk, cblk, crch, crcl; Uart_RxEmpty(); //接收缓冲区清空 if (mblock->nxt_num == )
{
if (mblock->crc_mode)
{
Uart_SendByte(MODEM_C);
}
else
{
Uart_SendByte(MODEM_NAK);
}
}
else
{
if (mblock->rec_err)
{
Uart_SendByte(MODEM_NAK);
}
else
{
if (mblock->nxt_num == )
{
if (mblock->crc_mode)
{
Uart_SendByte(MODEM_C);
}
else
{
Uart_SendByte(MODEM_NAK);
}
}
else
{
Uart_SendByte(MODEM_ACK);
}
}
}
while (!hd_found) //头字节
{
stat = Uart_RecvByteTimeout(&ch);
if (stat == )
{
switch (ch)
{
case MODEM_SOH :
hd_found = ;
mblock->len = ;
break;
case MODEM_STX :
hd_found = ;
mblock->len = ;
break;
case MODEM_CAN :
if ((++can_counter) >= MODEM_CAN_COUNT)
{
return ;
}
break;
case MODEM_EOT : //文件传输结束
if ((++eot_counter) >= MODEM_EOT_COUNT)
{
Uart_SendByte(MODEM_ACK);
if (mblock->modemtype == ) //Ymodem协议为批文件传输协议
{
Uart_SendByte(MODEM_C); //单个文件需 C ACK C后会自动停止传输
Uart_SendByte(MODEM_ACK);
Uart_SendByte(MODEM_C);
modem_cancle(); //多个文件强制停止传输
}
return ;
}
break;
default:
break;
}
}
else
{
return -;
}
} stat = Uart_RecvByteTimeout(&blk); //数据块错误或超时
if (stat != )
{
return -;
} stat = Uart_RecvByteTimeout(&cblk); //数块补码
if (stat != )
{
return -;
} for (i=; i < mblock->len ; i++)
{
stat = Uart_RecvByteTimeout(in_ptr++);
if (stat != )
{
return -;
}
} stat = Uart_RecvByteTimeout(&crch); //CRC
if (stat != )
{
return -;
} if (mblock->crc_mode)
{
stat = Uart_RecvByteTimeout(&crcl);
if (stat != )
{
return -;
}
} if (blk^cblk != 0xff)
{
return (-);
} if (mblock->crc_mode)
{
in_ptr = mblock->buf;
cksum = ; for (stat=mblock->len ; stat>; stat--)
{
cksum = cksum^(int)(*in_ptr++) << ;
for (i=; i!=; i--)
{
if (cksum & 0x8000)
cksum = cksum << ^ 0x1021;
else
cksum = cksum << ;
}
}
cksum &= 0xffff; if (cksum != (crch<< | crcl))
{
mblock->rec_err = ;
return (-);
}
}
else
{
for (i=; i<mblock->len; i++) //和校验方式
{
cksum += mblock->buf[i];
}
if ((cksum&0xff)!=crch)
{
mblock->rec_err = ;
return (-);
}
} mblock->cur_num = blk;
if (blk != mblock->nxt_num) //blk检查
{
return (-);
} mblock->nxt_num++;
mblock->rec_err = ;
return ;
} unsigned int buf_filelen(unsigned char *ptr)
{
int datatype=, result=; if (ptr[]=='' && (ptr[]=='x' && ptr[]=='X'))
{
datatype = ;
ptr += ;
} for ( ; *ptr!='\0'; ptr++)
{
if (*ptr>= '' && *ptr<='')
{
result =result*datatype+*ptr-'';
}
else
{
if (datatype == )
{
return result;
}
else
{
if (*ptr>='A' && *ptr<='F')
{
result = result* + *ptr-; //55 = 'A'-10
}
else if (*ptr>='a' && *ptr<='f')
{
result = result* + *ptr-; //87 = 'a'-10
}
else
{
return result;
}
}
}
}
return result;
} void modem_cancle(void)
{
Uart_SendByte(0x18);
Uart_SendByte(0x18);
Uart_SendByte(0x18);
Uart_SendByte(0x18);
Uart_SendByte(0x18);
}
ymodem协议c实现(转)的更多相关文章
- YModem协议
源:YModem协议 YModem协议: YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议. 下面先看下YModem协议传输的完整的握手过程: ...
- stm32 Bootloader设计(YModem协议) (转)
源:stm32 Bootloader设计(YModem协议) 相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootlo ...
- Ymodem协议说明
模块的固件烧录过程,由Term(发送方)发送固件文件,模块(接收方)接收并写入MCU,期间使用的数据传输协议是ymodem协议. 一.概述 ymodem协议是一种发送并等待的协议,即发送方发送一个 ...
- Ymodem协议(参考STM32)
相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootload设计.所以就仔细的去了研究了一翻.以前都是用的stm32官 ...
- ZYNQ使用ymodem协议传输文件
SDK: V2014.4 协议: Ymodem 工具: USB转UART转接线.xshell6软件 可实现各种文件传输,大小不限,只是速度很慢 参考原代码如下: /****************** ...
- python调用Moxa PCOMM Lite通过串口Ymodem协议发送文件
本文采用python 2.7编写. 经过长期搜寻,终于找到了Moxa PCOMM Lite.调用PCOMM.DLL可以非常方便的通过串口的Xmodem.Ymodem.Zmodem等协议传输文件,而无需 ...
- Kermit,Xmodem,1K-Xmodem,Ymodem,Zmodem传输协议小结
来自:http://blog.163.com/czblaze_3333/blog/static/208996228201272295236713/ Kermit协议 报文格式: 1. MA ...
- STM32 Bootloader基于ymodem传输协议串口IAP升级详解
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...
- STM32F103/429串口IAP+Ymodem升级
起因: 串口IAP升级在正点原子的例程中有讲解,正点原子的方法是:在RAM中开辟一个120K的数据空间,用来存放bin文件,bin文件通过串口一次性发送到单片机,然后再实现程序的跳转.但是这种方法在实 ...
随机推荐
- UVA106 - Fermat vs. Pythagoras
假设x为奇数,y为偶数,则z为奇数,2z与2x的最大公因数为2,2z和2x可分别写作 2z = (z + x) + (z - x) 2x = (z + x) - (z - x) 那么跟据最大公因数性质 ...
- POJ 3468<线段树,区间add>
题目连接 //位运算 k<<1 相当于 k*2 k<<1|1 相当于 k*2+1 /* 修改区间内的值,并且维护区间和. 详见代码 */ #include<cstdio& ...
- 快学Scala-第六章 对象
知识点: 1.单例对象 使用object语法结构达到静态方法和静态字段的目的,如下例,对象定义某个类的单个实例,包含想要的特性,对象的构造器在该对象第一次被使用时调用. object Account{ ...
- 《割绳子》《蜡笔物理学》《Contre Jour》《顽皮鳄鱼爱洗澡》等游戏用Box2D引擎实现物理部分的方法(转)
从最热门游戏排行榜和flash游戏网站上,你能看到什么?许多2D游戏都有非常出色的物理学和美术设计.现在我们要学习那些游戏使用了什么物理学以及如何用Box2D制作它们. 除了知道是“什么”,更重要的是 ...
- Win7下用easyBCD引导安装Ubuntu15.04
1 准备工作 easyBCD中添加一个启动项 修改启动项配置文件 注意两点:C盘设备号,镜像名称 title Install Ubuntu root (hd0,) kernel (hd0,)/vmli ...
- (三)、Struts第三天
(三).Struts第三天 Struts核心业务: (Struts提供了哪些功能?) 1. 请求数据自动封装(params拦截器) 2. struts数据处理方式 * ActionContext ...
- android 没有main函数,怎么找到程序执行入口呢?以及activity主要生命周期的方法说明
android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码之外生成的Activity,比如a ...
- 帝国CMS系统结合项图文教程
为了使信息列表可实现按多种条件输出数据,帝国CMS独创可设置无限条件的模型结合项功能.帝国CMS的结合项功能是指按模型多个字段内容来结合显示对应的信息. 二.结合项的语法说明 结合项访问地址: /e/ ...
- Nginx 502/504 Gateway time-out错误完美解决方案【转发】
在安装完Nginx+PHP-fpm+Mysql后,跑PHP的应用会经常出现504 Gateway Time-out 或者502 Bad Gateway的情况. Nginx 504 Gateway ...
- FFmpeg的Android平台移植—编译篇
摘要:本文主要介绍将FFmpeg音视频编解码库移植到Android平台上的编译和基本测试过程. 环境准备: ubuntu-12.04.5 android-ndk64-r10-linux-x86_64. ...