VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1043|回复: 5

如何通过XMODEM协议实现串口文件传输

[复制链接]

1

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-2-23 22:00:01 | 显示全部楼层 |阅读模式
双机间通过串口用xmodem协议传送文件,有谁有这方面的vc++例子代码。   
有类也行。需要的是xmodem文件传送协议类。如何传送文件,主要是发送
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-8-24 08:30:01 | 显示全部楼层
我也正在做这个,倒是找到一个类(megepipenet),具体里面实现却看不到。
有很多C写的程序。哪有它的具体过程的说明啊?
回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-8-24 09:00:01 | 显示全部楼层
XMODEM有好几种,你指哪种?XMODEM-CRC?XMODEM-1K?
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-8-24 09:15:01 | 显示全部楼层
Xmodem通信协议
Xmodem协议是一种使用拨号调制解调器的个人计算机通信中广泛使用的异步文件运输协议。这种协议以128/1k字节块的形式传输数据,并且每个块都使用一个校验和过程来进行错误检测。如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个认可字节。为了便于读者阅读程序,下面简要说明该协议的主要特点,有关Xmoden的完整的协议请参考其它相关的资料。

Xmodem的控制字符:<soh> 01H、<stx> 02H <eot> 04H、<ack> 06H、<nak> 15H、<can> 18H、<eof> 1AH。

Xmodem传输数据块格式:“<soh> <packNO> <255-packNO> <…128个字节的数据块…> <cksum>”。其中<soh>为起始字节;<packNO>为数据块编号字节,每次加一;<255-packNO>是前一字节的反码;接下来是长度为128字节的数据块;最后的<cksum>是128字节数据的校验码,长度为2个字节。

接收端主导整个传输。以发送<nak>或<stx>或'C'启动传输。控制字符“C”有特殊的作用,当发送端收到“C”控制字符时,它回重新开始以CRC校验方式发送数据块(packNO = 1)。CRC校验方式采用16位(X^16 + X^12 + X^5 + 1)。送端收到第一个<nak>时以checksum方式开始发送。送端收到第一个<stx>时以1k-crc方式开始发送。接收端收到一个数据块并校验正确时,回送<ack>;接收错误回送<nak>;而回送<can>表示要发送端停止发送。发送端收到<ack>后,可继续发送下一个数据块(packNO+1)。每发送一个新的数据块<packNO>加1,加到OxFF后下一个数据块的<packNO>为零。而收到<nak>则可再次重发上一个数据块。发送端发送<eot>表示全部数据发送完成。如果最后需要发送的数据不足128个字节,用<eof>填满一个数据块。
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-8-24 09:30:01 | 显示全部楼层
C写的,原理一样

#define XYMODEM_SOH 0x01
#define XYMODEM_STX 0x02
#define XYMODEM_EOT 0x04
#define XYMODEM_ACK 0x06
#define XYMODEM_BSP 0x08
#define XYMODEM_NAK 0x15
#define XYMODEM_CAN 0x18
#define XYMODEM_EOF 0x1A  // ^Z for DOS officionados

int Xmodem_SendData(unsigned int addr, unsigned int size)
{
    com_addr=xmodem_init();
    int res;
        int file_len;
        file_len=size;
        unsigned char *p=(unsigned char *)addr;
        unsigned char  pack_num;
        pack_num=1;
        int i;
        unsigned short check_sum;
        check_sum=0;
        char c;
        int count;
        count=129;
           while(file_len>0)
        {
                res = CYGACC_COMM_IF_GETC_TIMEOUT(com_addr, &c);
                if(file_len<128)
                {
                count=file_len;
                }
                if(!res)
                {
                        continue;
                }
                if(c==XYMODEM_CAN)
                {
                        return -1;
                }
                if((pack_num!=1)&&(c==XYMODEM_NAK))
                {
                        write_char(XYMODEM_SOH);
                        pack_num-=1;
                        write_char(pack_num);
                        write_char(~pack_num);
                        pack_num++;
                        p=p-128;
                        for(i=0;i<128;i++)
                        {   
                                if(i<count)
                                {
                                write_char(*p);
                                check_sum+=*p;
                                p++;
                                }
                                else
                                {
                                write_char(XYMODEM_EOF);
                                check_sum+=XYMODEM_EOF;
                                }
                        }
                        write_char(check_sum);
                        check_sum=0;
                       
                }
                else
                {
                        write_char(XYMODEM_SOH);
                        write_char(pack_num);
                        write_char(~pack_num);
                        pack_num++;
                        for(i=0;i<128;i++)
                        {  
                                if(i<count)
                                {
                                write_char(*p);
                                check_sum+=*p;
                                p++;
                                }
                                else
                                {
                                write_char(XYMODEM_EOF);
                                check_sum+=XYMODEM_EOF;
                                }
                        }
                        write_char(check_sum);
                        check_sum=0;
                       
                }
               
               
                file_len-=128;
        }
    write_char(XYMODEM_EOT);

        xmodem_flush();
     
         return 0;

} /* end function Xmodem_SendData */

回复

使用道具 举报

0

主题

1

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-9-4 17:00:01 | 显示全部楼层
学习学习,谢谢分享!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表