📄 xmodem.c
字号:
#include "xmodem.h"
/* 读取单个数据包 */
/* 返回0表示读取数据包成功 */
/* 返回1表示数据包不完整 */
/* 返回2表示数据包检验和出错 */
static
int RecFrame(struct Frame* oneFrame)
{
int returnVal; // 返回的值
int i;
oneFrame->blkNum = sio_getc();
oneFrame->blkNumRev = sio_getc();
// 检验数据包完整性
if( oneFrame->blkNumRev != 255 - (oneFrame->blkNum & 0xFF))
returnVal = 1;
else
{
// 读取数据区
for(i = 0; i < BLOCK_SIZE; ++i)
{
oneFrame->dataBlk[i] = sio_getc();
}
// 检验累加校验和
oneFrame->checkSum = sio_getc();
if(oneFrame->checkSum == CheckSum(oneFrame))
returnVal = 0;
else
returnVal = 2;
}
return (returnVal);
}
// Xmodem协议传输执行函数
void XmodemRun(char *ptr)
{
struct Frame dataFrame;
do
{
DelayTime(ONE_SECOND);
sio_putc(NAK);
} while(!sio_ischar());
do
{
switch(sio_getc())
{
// 控制字符为SOH,则接收该数据包
case SOH:
switch( RecFrame(&dataFrame) )
{
// 数据包接收正常,发送ACK消息,将数据区的数据拷贝到内存
case 0:
MemCpy(ptr, dataFrame.dataBlk, BLOCK_SIZE);
ptr += BLOCK_SIZE;
sio_putc(ACK);
break;
// 数据包接收错误,发送NAK消息
case 1: case 2:
sio_putc(NAK);
break;
}
break;
case EOT:
sio_putc(ACK);
*(++ptr) = 0; // 给存储区域的最后一个字节赋值0,终止sio_puts()
return;
case CAN:
return;
default:
break;
}
} while(1);
}
// 延时函数
static
void DelayTime(int time)
{
int i;
for(i = 0; i < time; ++i)
;
}
// 将数据区的数据拷贝到内存中
static
void MemCpy(char des[], char src[], int length)
{
int i;
for(i = 0; i < length; ++i)
{
des[i] = src[i];
}
}
// 计算校验和,返回校验和!!!!!!
static
unsigned char CheckSum(struct Frame *oneFrame)
{
int i;
unsigned char dataSum = 0x00;
for(i = 0; i < BLOCK_SIZE; ++i)
{
dataSum += oneFrame->dataBlk[i];
}
return (dataSum & 0xff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -