源: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实现(转)的更多相关文章

  1. YModem协议

    源:YModem协议 YModem协议: YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议. 下面先看下YModem协议传输的完整的握手过程: ...

  2. stm32 Bootloader设计(YModem协议) (转)

    源:stm32 Bootloader设计(YModem协议) 相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootlo ...

  3. Ymodem协议说明

      模块的固件烧录过程,由Term(发送方)发送固件文件,模块(接收方)接收并写入MCU,期间使用的数据传输协议是ymodem协议. 一.概述 ymodem协议是一种发送并等待的协议,即发送方发送一个 ...

  4. Ymodem协议(参考STM32)

    相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootload设计.所以就仔细的去了研究了一翻.以前都是用的stm32官 ...

  5. ZYNQ使用ymodem协议传输文件

    SDK: V2014.4 协议: Ymodem 工具: USB转UART转接线.xshell6软件 可实现各种文件传输,大小不限,只是速度很慢 参考原代码如下: /****************** ...

  6. python调用Moxa PCOMM Lite通过串口Ymodem协议发送文件

    本文采用python 2.7编写. 经过长期搜寻,终于找到了Moxa PCOMM Lite.调用PCOMM.DLL可以非常方便的通过串口的Xmodem.Ymodem.Zmodem等协议传输文件,而无需 ...

  7. Kermit,Xmodem,1K-Xmodem,Ymodem,Zmodem传输协议小结

    来自:http://blog.163.com/czblaze_3333/blog/static/208996228201272295236713/ Kermit协议 报文格式: 1.       MA ...

  8. STM32 Bootloader基于ymodem传输协议串口IAP升级详解

    硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...

  9. STM32F103/429串口IAP+Ymodem升级

    起因: 串口IAP升级在正点原子的例程中有讲解,正点原子的方法是:在RAM中开辟一个120K的数据空间,用来存放bin文件,bin文件通过串口一次性发送到单片机,然后再实现程序的跳转.但是这种方法在实 ...

随机推荐

  1. Java Networking Related (Java Examples in a Nutshell 3rd Edition)

    Examples to: Use URL class to parse URLs and download the network resources specified by a URL Use U ...

  2. php 日期处理 例子

    <?php date_default_timezone_set('PRC'); //默认时区 echo "今天:",date("Y-m-d",time() ...

  3. Android中如何将Bitmap byte裸数据转换成Bitmap图片int数据

    Android中如何将Bitmap byte裸数据转换成Bitmap图片int数据 2014-06-11 10:45:14   阅读375次 我们在JNI中处理得到的BMP图片Raw数据,我们应该如何 ...

  4. frameset导航框架

    1.制作导航框架(注意"name='mainframe'") <html> <frameset cols="25%,75%"> < ...

  5. UVALive 2522 Chocolate(概率DP)

    思路:定义DP方程dp[i][j]标记选到第i个巧克力的时候,桌面上还剩下j个巧克力,状态转移有两个方向,dp[i-1][j-1],dp[i-1]lj+1],分别表示桌面上多了一个和消了一个,乘上需要 ...

  6. android ApplicationContext Context Activity 内存的一些学习

    Android中context可以作很多操作,但是最主要的功能是加载和访问资源. 在android中有两种context,一种是application context,一种是activity cont ...

  7. Windows下Apache+Django+mod_wsgi的static和media问题处理

    配置好了Apache可以访问Django工程了(参见前篇:Windows编译安装mod_wsgi,配合使用Django+Apahce) 但是Django中的static.media等文件Apache是 ...

  8. 使用for循环还是foreach循环?

    很多时候我们很自然的认为,for循环的时候使用foreach和原来的for循环用下标的方式遍历是相同的. 而且因为foreach循环写法简单,很容易理解,而且少去了很多麻烦的变量,所以估计在学会使用f ...

  9. Mysql 随机查询数据

    SELECT * FROM tablename ORDER BY RAND() LIMIT 10

  10. Android传感器编程带实例(转)

    源:http://www.cnblogs.com/xiaochao1234/p/3894751.html 看了程序人生 网站的 编程高手的编程感悟 深有感触,好像也是一个android 程序员写的,推 ...