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文件通过串口一次性发送到单片机,然后再实现程序的跳转.但是这种方法在实 ...
随机推荐
- SqlServer 查询死锁,杀死死锁进程
-- 查询死锁 select request_session_id spid, OBJECT_NAME(resource_associated_entity_id) tableName from sy ...
- UIImage+Scale
Scale a UIImage to any given rect keeping the aspect ratio Raw UIImage+Scale.m @implementation UI ...
- ubuntu server 11.10 mysql 自动备份脚本
1.下载最新的备份脚本(AutoMySQLBackup) 点这里下载 2.修改脚本配置部分 vi /root/automysqlbackup-2.5.1-01.sh USERNAME=root PA ...
- 转:Web安全与Rational AppScan入门
Web 应用的基础概念 在讨论 Web 应用安全之前,先简单介绍一下 Web 应用基础概念,这样便于理解为什么 Web 应用是脆弱的,容易受到攻击. 1. 什么是 Web 应用 Web 应用是由动态脚 ...
- Effective java -- 4 泛型
第二十三条:请不要在代码中使用原生态类型就是像Set这种待泛型的,就把泛型明确写出来. 第二十四条:消除非受检警告就是Set<String> sets = new HashSet();这种 ...
- 第13章 Swing程序设计----常用面板
面板也是一个Swing容器,它可以作为容器容纳其他组件,但它也必须被添加到其他容器中. Swing常用的面板包括JPanel面板和JScrollPanel面板. 1.JPanel面板 import j ...
- 我的android学习脚步----------- 的第一个应用
刚刚开始学android开发,以前都是在别人调好的应用中修改JNI,现在需要自己一步步走 开发环境:Eclipse+ADT 配置不多讲了,引自:http://www.cnblogs.com/allen ...
- 设计一个 iOS 控件
转载自:http://blog.csdn.net/zhangao0086/article/details/45622875 代码的等级:可编译.可运行.可测试.可读.可维护.可复用 前言 一个控件从外 ...
- hrbustoj 2130 一笔画(状态压缩)
基础状态压缩 转移方程为 dp[j][i] = min(dp[j][i],dp[k][i^(1<<j)] + dis[k][j]); #include<iostream> #i ...
- 深入浅出Ajax(一)
客户端: <script type="text/javascript"> window.onload = initPage; function initPage() { ...