📄 xmodem.c
字号:
#define IN_XMODEM
#include "config.h"
//uint8 a;
extern void setUart0TimeoutVal(int);
extern int getUart0TimeoutVal(void);
extern INT8U getUar0ErrMsg(void);
char rcvChar(INT8U * errInfo)
{
char ch;
setUart0TimeoutVal(2*OS_TICKS_PER_SEC);
ch=getchar();
*errInfo=getUar0ErrMsg();
setUart0TimeoutVal(0);
return ch;
}
BOOL xModemDownload()
{
INT8U errInfo;
char ch=0;//临时变量
int pktSeqNum=0,seqNum=0;//发方序列号,收方序列号
int pktCpltSeqNum=0;//发方序列号的补码
int pktChkSum=0,chkSum=0;//发方校验和,收方校验和
INT8U firstPktFlag=0;//第一个包标志
INT8U i;
Begin:
while(1)
{
if(firstPktFlag==0)putchar(NAK);
ch=rcvChar(&errInfo);//取包起始字符,如果是SOH表示开始传输一个包,如果是SOH则有可能是文件传输已结束
if(errInfo==OS_TIMEOUT) continue;
if(ch==SOH)break;//如果是包头继续接收下一下字符
if(ch==CAN)goto end;//如果是取消传遂,则进行传输结束处理
if(ch==EOT)//如果文件已接收完继续判断是否再次收到EOT,确认是否真的结束
{
putchar(NAK);//如果是文件结束消息,则进行传输结束处理
ch=rcvChar(&errInfo);
if(errInfo==OS_TIMEOUT)goto end;
if(ch==EOT)
{
putchar(ACK);
return TRUE;//文件传输成功
}
else
{
return FALSE;//如果只收到一个EOT,也认为文件传输不成功
}
}
}
//printf("SOH recieved\r\n");
pktSeqNum=rcvChar(&errInfo);//取包序号
if(errInfo==OS_TIMEOUT)goto end;
if(firstPktFlag==0)
{
seqNum=pktSeqNum;//如果是第一个包,把序号赋给收方作为收方序号计数初值
firstPktFlag=1;
}
else
{
if(pktSeqNum!=(seqNum))goto end;//如果包序号不对,中止传输
}
//printf("pktSeqNum recieved\r\n");
pktCpltSeqNum=rcvChar(&errInfo);;//取包序号的补码
if(errInfo==OS_TIMEOUT)goto end;
if(pktCpltSeqNum!=(255-seqNum))goto end;
//printf("comPktSeqNum recieved\r\n");
chkSum=0;
for(i=0;i<128;i++) //接收数据包并计算检验和
{
ch=rcvChar(&errInfo);
if(errInfo==OS_TIMEOUT)goto end;
chkSum=(chkSum+ch)%256;
}
//printf("128byte recieved\r\n");
pktChkSum=rcvChar(&errInfo);//取包校验和
if(errInfo==OS_TIMEOUT)goto end;
if(chkSum==pktChkSum)
{
putchar(ACK);
seqNum=(seqNum+1)%256; //计算下一个序号
}
else
{
putchar(NAK);
}
//printf("chksum=%x\r\n",chkSum);
goto Begin;
end:
putchar(CAN);
putchar(CAN);
putchar(CAN);
putchar(CAN);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -