读书人

嵌入式linux上串口采用xmodem协议 接受

发布时间: 2012-12-31 11:57:52 作者: rapoo

嵌入式linux下串口采用xmodem协议 接受不成功
接受时总是无法接受完整的包而超出最大次数,最后退出程序, 请问是什么原因? 怎么改?

int xmodemReceive(int fd, char *dest, int destsz)
{
unsigned char xbuff[38]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
//unsigned char *p;
int bufsz, crc = 0;
unsigned char c, trychar = 'C';
unsigned char packetno = 1;
int len = 0;
int retry, retrans = MAXRETRANS;
for(;;)
{
for( retry = 0; retry < 4; ++retry)
{
if (trychar)
port_outbyte(fd, trychar);
}
while(c != SOH){
c = port_inbyte(fd);
if(c == EOT || c == CAN)
break;
}//(DLY_1S)<<1);
if (last_error == 0)
{
switch (c)
{
case SOH:
bufsz = 32;


goto start_recv;
case EOT:
flushinput();
port_outbyte(fd, ACK);
return len; /* normal end */
case CAN:
c = port_inbyte(fd);//DLY_1S);
if (c == CAN)
{
flushinput();
port_outbyte(fd, ACK);
return -1; /* canceled by remote */
}


break;
default:
break;
}
}

if (trychar == 'C')
{
trychar = NAK;
continue;
}
flushinput();
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
return -2; /* sync error */
start_recv:
if (trychar == 'C') crc = 1;
trychar = 0;
usleep(10000);
retry = read(fd, xbuff, 38);
if (retry < 37)
{
printf("last_error2=%d\n", retry);
goto reject;
}
if (xbuff[1] == (unsigned char)(~xbuff[2]) &&
(xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) &&


check(crc, &xbuff[3], bufsz))
{
if (xbuff[1] == packetno)
{
int count = destsz - len;
if (count > bufsz)
count = bufsz;
if (count > 0)
{
memcpy (&dest[len], &xbuff[3], count);
len += count;
}
++packetno;
printf("count=%d len=%d packetno=%d\n", count, len, packetno);
retrans = MAXRETRANS+1;
}
if (--retrans <= 0)
{
flushinput();
port_outbyte(fd, CAN);


port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
return -3; /* too many retry error */
}
port_outbyte(fd, ACK);
continue;
}
reject:
flushinput();
c = port_inbyte(fd);
printf("rej=%d\n", c);
port_outbyte(fd, NAK);
}
}

int xmodemTransmit(int fd, unsigned char *src, int srcsz)
{
unsigned char xbuff[38]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
int bufsz, crc = -1;
unsigned char packetno = 1;
int c, len = 0;
int retry;
for(;;)
{
//for( retry = 0; retry < 16; ++retry)
//{
while(c != 'C'){
c = port_inbyte(fd);
if(c == NAK || c == CAN)
break;
}//(DLY_1S)<<1);
if (last_error == 0)
{
switch (c)
{
case 'C':
crc = 1;
goto start_trans;
case NAK:
crc = 1;
goto start_trans;
case CAN:
c = port_inbyte(fd);//DLY_1S);
if (c == CAN)
{
port_outbyte(fd, ACK);
flushinput();
return -1; /* canceled by remote */
}
break;
default:
break;
}
}
//}
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
flushinput();
return -2; /* no sync */
for(;;)
{
start_trans:
xbuff[0] = SOH; bufsz = 32;
xbuff[1] = packetno;
xbuff[2] = ~packetno;
c = srcsz - len;
printf("c1=%d \n", c);
if (c > bufsz) c = bufsz;
if (c >= 0)
{
memset (&xbuff[3], 0, bufsz);
if (c == 0)
{


xbuff[3] = CTRLZ;
}
else
{
memcpy (&xbuff[3], &src[len], c);
if (c < bufsz) xbuff[3+c] = CTRLZ;
}
if (crc)
{
unsigned short ccrc = crc16_ccitt(&xbuff[3], bufsz);
xbuff[bufsz+3] = (ccrc>>8) & 0xFF;
xbuff[bufsz+4] = ccrc & 0xFF;
}
for (retry = 0; retry < MAXRETRANS; ++retry)
{
usleep(100000);
write(fd, xbuff, 38);
usleep(10000);
c = port_inbyte(fd);//DLY_1S);
if (last_error == 0 )
{
switch (c)
{
case ACK:
printf("ACK=%d\n", c);
++packetno;
len += bufsz;
goto start_trans;
case CAN:
c = port_inbyte(fd);//DLY_1S);
if ( c == CAN)
{
port_outbyte(fd, ACK);
flushinput();
return -3; /* canceled by remote */
}
break;
case NAK:
printf("NAK=%d\n", c);
//break;
default:
break;
}
}
}
printf("C=%d\n", c);
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
port_outbyte(fd, CAN);
flushinput();
return -4; /* xmit error */
}
else
{
for (retry = 0; retry < 10; ++retry)
{
port_outbyte(fd, EOT);
c = port_inbyte(fd);//(DLY_1S)<<1);
if (c == ACK) break;
}
flushinput();
return (c == ACK)?len:-5;
}
}
}
}


[解决办法]
楼主 有完整的程序嘛 发份看下 linuxarmcom@163.com

读书人网 >UNIXLINUX

热点推荐