📄 xmodem_receive.c
字号:
static unsigned char xmodem_buff[128+4];
static unsigned char xmodem_block_number;
static int xmodem_index = -1;
static int get_xmodem_frame(void) //接受数据子函数
{
TIMER timeout;
int index;
int c;
xmodem_index = -1;
//set_timer(&timeout, ONE_SECOND*10 );
Delay(1000);
do {
c = getchar();
} while(c < 0 && ! timer_expired(&timeout));
if(c < 0) return -1; //返回值如果小于0则为原则性错误,停止传输
if(c != XMODEM_SOH && c != XMODEM_EOT && c != XMODEM_CAN) //如果是开始、结束或者停止标志位返回
{
Delay(1000);
do {
c = getchar();
if(c >= 0) Delay(1000);
} while( ! timer_expired(&timeout));
return -1; //返回值如果小于0则为原则性错误,停止传输
}
index = 0;
xmodem_buff[index++] = c; //接受开始SOH数据
if(c == XMODEM_EOT || c == XMODEM_CAN) return 0; //返回值如果为0则为终止或者结束标志
while(index < sizeof(xmodem_buff))
{
Delay(1000);
do {
c = getchar();
} while(c < 0 && ! timer_expired(&timeout));
if(c < 0) return -1; //返回值如果小于0则为原则性错误,停止传输
xmodem_buff[index++] = c; //接受数据DATA
}
xmodem_index = 0; //接受完毕
return 0;
}
static int xmodem_verify_frame(void) //校验子函数累加和
{
int i;
unsigned char checksum;
//检测数据包的SOH、包号和包号的补码
if(xmodem_buff[0] != XMODEM_SOH) return -1; //原则性错误
if(xmodem_buff[1] != xmodem_block_number) return -1;
if(xmodem_buff[2] != ((~xmodem_block_number) & 0xff)) return -1;
//检测累加和
checksum = 0;
for(i = 3; i < sizeof(xmodem_buff)-1; i++) checksum += xmodem_buff[i];
if(checksum != xmodem_buff[sizeof(xmodem_buff)-1]) return -1; //校验和不对
return 0; //成功
}
static int xmodem_get_more(void) //获得更多数据包
{
int err;
int err_retry_count;
xmodem_block_number++;
err_retry_count = 0;
while(err_retry_count < XMODEM_ERR_RETRY_COUNT)
{
if(xmodem_index < 0) putchar(XMODEM_NAK); //发出重发信号
err = get_xmodem_frame();//得到下一组数据
if(err == 0)
{
if(xmodem_buff[0] == XMODEM_SOH)
{
if( xmodem_verify_frame() == 0) //校验码成功
{
putchar(XMODEM_ACK); //传输成功
xmodem_index = 3;
return 0;
}
else if(xmodem_buff[1] == xmodem_block_number -1)
putchar(XMODEM_ACK); //uart_sendchar
else {
xmodem_index = -1;
}
err_retry_count++;
continue;
}
else if(xmodem_buff[0] == XMODEM_EOT)
{
putchar(XMODEM_ACK);
xmodem_index = -1;
return -1;
}
}
xmodem_index = -1;
err_retry_count++;
}
xmodem_index = -1;
return -2;
}
static int xmodem_eof(void)
{
int i;
if(xmodem_index < 0) return 1;
for( i = xmodem_index; i < sizeof(xmodem_buff) -1; i++)
{
if(xmodem_buff[i] != XMODEM_EOF) return 0;
}
if(peekchar() != XMODEM_EOT) return 0;
return 1;
}
int xmodem_start(void)
{
xmodem_index = sizeof(xmodem_buff)-1;
xmodem_block_number = 0;
return 0;
}
int xmodem_finish(void)
{
int c;
do {
c = xmodem_getchar();
} while(c >= 0);
return 0;
}
int xmodem_abort(void)
{
int i;
for(i=0; i<8; i++)
putchar(XMODEM_CAN);
xmodem_finish();
return 0;
}
/****************************************************************
* This is the user api call for xmodem transfers.
*
*
*/
int xmodem_getchar(void)
{
int err;
int c;
if(xmodem_index < 0) return -1;
if(xmodem_index >= sizeof(xmodem_buff)-1)
{
err = xmodem_get_more();
if(err < 0) return err;
}
c = xmodem_buff[xmodem_index];
xmodem_index++;
if(c == XMODEM_EOF) {
if( xmodem_eof() ) {
xmodem_finish();
xmodem_index = -1;
return -1;
}
}
return c;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -