ZYNQ使用ymodem协议传输文件
SDK: V2014.4
协议: Ymodem
工具: USB转UART转接线、xshell6软件
可实现各种文件传输,大小不限,只是速度很慢
参考原代码如下:
/*******************************************************************************
* @函数名称 YmodemRecvData
* @函数说明 使用Ymodem协议接收数据
* @输入参数 data :数据
size :长度
* @输出参数 无
* @返回参数 数据包的总大小
*******************************************************************************/
int YmodemRecvData(void)
{
int i=0;
char ErrorNum=0; //错误计数
char YmodemState=0;
unsigned char TempChar=0; //接收数据
int crcvalue=0;
int len=0;
int count=0;
ErrorNum=0;
while(1)
{
switch(YmodemState)
{
case 0: //通信起始阶段
SerialPutChar(CRC16); //发起始信号
if(GetKeyC(1000000,&TempChar)==0) //每次等待0.2s钟,发生超时重发“C”
{
if(TempChar==SOH )
{
GetKey(&TempChar);
if(TempChar!=0x00)return ; //不是00序号。
GetKey(&TempChar);
if ( TempChar != 0xFF )return ; //不是00序号补码。
for ( i=0; i<128; i++ )
{ //接收数据包0,共128字节
GetKey((UserBuf+i));
}
GetKey(&TempChar);
GetKey(&TempChar); //丢弃CRC校验,暂时不想实现。
SerialPutChar(ACK); //发送确认信号。
YmodemState=1; //状态切换到数据传输状态
for ( i=0; i<128; i++ )
{ //接收数据包0,共128字节
file_name[i]=0;
}
for ( i=0; (i<128)&&(UserBuf[i]); i++ )
{ //接收数据包0,共128字节
file_name[i]=UserBuf[i];
}
Str2Int((UserBuf+i+1),&PackLen);
SerialPutChar (CRC16); //再发一个C,正式启动数据传输
}
}
break;
case 1: //数据传输阶段
GetKey(&TempChar);
switch(TempChar)
{
case EOT: YmodemState = EOT;
SerialPutChar ( ACK );
continue;
case SOH:
len = 128;
break;
case STX:
len = 1024;
break;
case ABORT1:
Serial_PutString("用户取消文件传输!\r\n");
return PackLen;
case ABORT2:
Serial_PutString("用户取消文件传输!\r\n");
return PackLen;
default :return PackLen;
} //end of switch (StartChar)
GetKey(&TempChar);
GetKey(&TempChar);
for(i=0;i<len;i++)
{ //接收整个数据包
GetKey((UserBuf+i));
}
//CRC桥验
GetKey(&TempChar);
crcvalue=TempChar;
crcvalue<<=8;
GetKey(&TempChar);
crcvalue|=TempChar;
if(Cal_CRC16(UserBuf,len)!=crcvalue)
{
ErrorNum+=1;
}
if(ErrorNum==0)
{
SerialPutChar(ACK);
count+=len;
}
else SerialPutChar(NAK); //接收发现错误,要求重发。
break;
case EOT: //结束传输阶段
SerialPutChar(CRC16);
GetKey(&TempChar); //接收起始字符。
if(TempChar==SOH)
{
GetKey(&TempChar);
if(TempChar!=0x00)return PackLen; //不是00序号。
GetKey(&TempChar);
if(TempChar!=0xFF)return PackLen; //不是00序号补码。
for(i=0;i<128;i++)
{
GetKey((UserBuf+i));
}
//CRC桥验
GetKey(&TempChar);
crcvalue=TempChar;
crcvalue<<=8;
GetKey(&TempChar);
crcvalue|=TempChar;
if(Cal_CRC16(UserBuf,128)!=crcvalue)
{
ErrorNum+=1;
}
if(ErrorNum==0)
{
SerialPutChar(ACK);
return PackLen;
}
else SerialPutChar(NAK); //接收发现错误,要求重发。
break;
}
default:
return PackLen;
}
}
return PackLen;
}
结合ZYNQ代码改写如下函数:
void SerialPutChar(uint8_t c)
{
volatile int i = 0;
XUartPs_SendByte(STDOUT_BASEADDRESS, c);
for(i=0; i<1500; i++)
{
;
}
}
unsigned char GetKeyC(unsigned int count,unsigned char *key)
{
volatile int i = 0;
volatile unsigned long temp;
for(i=0;i<count;i++)
{
}
for(i=0;i<1000;i++)
{
temp = MyUart_RecvByte();
if( (temp &0xFFFFFF00) == 0 )
{
*key = (unsigned char)(temp & 0x000000FF);
return 0;
}
}
return 1;
}
uint8_t GetKey(uint8_t *key)
{
volatile unsigned long temp;
volatile int i ;
for(i=0; i<1000;i++)
{
temp = MyUart_RecvByte();
if( (temp &0xFFFFFF00) == 0 )
{
*key = (unsigned char)(temp & 0x000000FF);
return (*key);
}
}
return 0;
}
可以通过Ymodem正确传输完成文件,但还存在的问题如下:
1、第一包数据:STX 00 FF .... 的CRC16校验码会变为0xFF或其他不对的值,导致校验失败。而除了第一包后面的校验都是正确的。
2、用xshell6才能正确传输,用超级终端或者secureCRT都会有几包错误数据。且每次都是错的那几包。
3、传输到一半点击取消后,代码不再运行,需要重启。
4、文件传输完成界面不动,必须按下回车键,才会结束传输过程。
ZYNQ使用ymodem协议传输文件的更多相关文章
- python调用Moxa PCOMM Lite通过串口Ymodem协议发送文件
本文采用python 2.7编写. 经过长期搜寻,终于找到了Moxa PCOMM Lite.调用PCOMM.DLL可以非常方便的通过串口的Xmodem.Ymodem.Zmodem等协议传输文件,而无需 ...
- 开发错误日志之FTP协议传输文件问题
从开发端用FTP协议向服务器(Linux系统)传输文件时,cat -A查询文件内容中行尾会有^M出现. 解决方案:改用SFTP协议上传文件.
- Netty--使用TCP协议传输文件
简介: 用于将文件通过TCP协议传输到另一台机器,两台机器需要通过网络互联. 实现: 使用Netty进行文件传输,服务端读取文件并将文件拆分为多个数据块发送,接收端接收数据块,并按顺序将数据写入文件. ...
- 一个ftp协议传输文件之后执行脚本无法工作的情况
作者:良知犹存 转载授权以及围观:欢迎添加微信号:Conscience_Remains 总述 移植一个文件系统时候,我在window下git clone了对方仓库源码,然后用FileZ ...
- 用java pyhont通过HTTP协议传输文件流
// 代码网上抄的 忘记链接了 抱歉哈package upload; import java.io.BufferedReader; import java.io.DataOutputStream; i ...
- YModem协议
源:YModem协议 YModem协议: YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议. 下面先看下YModem协议传输的完整的握手过程: ...
- stm32 Bootloader设计(YModem协议) (转)
源:stm32 Bootloader设计(YModem协议) 相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootlo ...
- Ymodem协议(参考STM32)
相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些.下文中的bootload就来实现这样的功能. 前段时间有项目关于Bootload设计.所以就仔细的去了研究了一翻.以前都是用的stm32官 ...
- KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结(转)
源:KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结 Kermit协议 报文格式: 1.MARK,起始标记START_CHAR,为 0x01(CTRIL-A): 2.LEN,报文剩余 ...
随机推荐
- JavaGuide--Java篇
本文避免重复造轮子,也是从JavaGuider中提取出来方便日后查阅的手册 参考链接: JavaGuider:https://javaguide.cn/java/basis/java-basic-qu ...
- docker | jenkins 实现自动化CI/CD,后端躺着把运维的钱挣了!(下)
前言 在上一篇文章中,我们使用docker编写Dockerfile文件,将我们自己的项目构建成镜像,然后发布到Docker Hub中,并且用自己的云服务器拉取Docker Hub上我们自己上传的项目镜 ...
- Spring中@Autowired 注解的注入规则
默认根据类型,匹配不到则根据bean名字 1.声明一个service接口 public interface HelloService { void sayHello(); } 2.service接口的 ...
- Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器,包括Spring Security和Spring Boot
2月14日,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器. 其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队将不再提供 ...
- 扯 C++ 里的 Lambda
之前写(抄) parsec 的时候, 在重载 operator>> 的时候, operator>> 需要接收一个 lambda, 之后返回一个 Component<R&g ...
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- 实体类分层命名PO,VO,BO,DTO,POJO,DAO,DO
一.Java中PO.DO.TO.DTO. VO. BO.POJO .DAO的概念 PO:persistant object持久对象 最形象的理解就是一个PO就是数据库中的一条记录.好处是可以把一条记录 ...
- 容器化 | 在 KubeSphere 中部署 MySQL 集群
程润科 数据库研发工程师,目前从事 RadonDB MySQL Kubernetes 研发,热衷于研究数据库内核.K8s 相关技术. 张莉梅 高级文档工程师,目前负责数据库产品文档开发.维护和管理工作 ...
- Android 连接蓝牙扫码器 无输入框
Android 的APP 需要集成一个蓝牙扫码器, 特别的是,需要扫码的地方是没有输入框的(EditText),不能通过直觉上理解的通过对EditText输入事件进行监听处理,取得扫码结果.并且设备也 ...
- .Net Core AOP之IExceptionFilter
一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...