首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

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

2012-12-31 
嵌入式linux下串口采用xmodem协议 接受不成功接受时总是无法接受完整的包而超出最大次数,最后退出程序, 请

嵌入式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

热点排行