zoukankan      html  css  js  c++  java
  • 文件传输(xmodem协议)

     https://www.menie.org/georges/embedded/

    需要移植如下两个基础读写函数

    int _inbyte(unsigned short timeout);

    void _outbyte(int c);

     xmodem.c

    /*    
     * Copyright 2001-2010 Georges Menie (www.menie.org)
     * All rights reserved.
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *     * Neither the name of the University of California, Berkeley nor the
     *       names of its contributors may be used to endorse or promote products
     *       derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /* this code needs standard functions memcpy() and memset()
       and input/output functions _inbyte() and _outbyte().
    
       the prototypes of the input/output functions are:
         int _inbyte(unsigned short timeout); // msec timeout
         void _outbyte(int c);
    
     */
    
    #include "crc16.h"
    
    #define SOH  0x01
    #define STX  0x02
    #define EOT  0x04
    #define ACK  0x06
    #define NAK  0x15
    #define CAN  0x18
    #define CTRLZ 0x1A
    
    #define DLY_1S 1000
    #define MAXRETRANS 25
    
    void _outbyte(int c)
    {
            while ((readb(UTX1) & 0x20) == 0)
                    ;
    
            writeb ((char)c,UTX1+1);
    }
    
    void outbyte(int c)
    {
            static char prev = 0;
            if (c < ' ' && c != '
    ' && c != '
    ' && c != '	' && c != '')
                    return;
            if (c == '
    ' && prev != '
    ') _outbyte('
    ');
            _outbyte(c);
            prev = c;
    }
    
    int _inbyte(unsigned short timeout) // msec timeout
    {
            unsigned short c;
            int delay = timeout << 4;
    
            while (((c=readw(URX1)) & 0x2000) == 0) {
                    usleep(60); /* 60 us * 16 = 960 us (~ 1 ms) */
                    if (timeout) {
                            if (--delay == 0) return -2;
                    }
            }
    
            return c & 0x0FF;
    }
    
    unsigned short crc16_ccitt( const void *buf, int len )
    {
        unsigned short crc = 0;
        while( len-- ) {
            int i;
            crc ^= *(char *)buf++ << 8;
            for( i = 0; i < 8; ++i ) {
                if( crc & 0x8000 )
                    crc = (crc << 1) ^ 0x1021;
                else
                    crc = crc << 1;
            }
        }
        return crc;
    }
    
    static int check(int crc, const unsigned char *buf, int sz)
    {
        if (crc) {
            unsigned short crc = crc16_ccitt(buf, sz);
            unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
            if (crc == tcrc)
                return 1;
        }
        else {
            int i;
            unsigned char cks = 0;
            for (i = 0; i < sz; ++i) {
                cks += buf[i];
            }
            if (cks == buf[sz])
            return 1;
        }
    
        return 0;
    }
    
    static void flushinput(void)
    {
        while (_inbyte(((DLY_1S)*3)>>1) >= 0)
            ;
    }
    
    int xmodemReceive(unsigned char *dest, int destsz)
    {
        unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
        unsigned char *p;
        int bufsz, crc = 0;
        unsigned char trychar = 'C';
        unsigned char packetno = 1;
        int i, c, len = 0;
        int retry, retrans = MAXRETRANS;
    
        for(;;) {
            for( retry = 0; retry < 16; ++retry) {
                if (trychar) _outbyte(trychar);
                if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
                    switch (c) {
                    case SOH:
                        bufsz = 128;
                        goto start_recv;
                    case STX:
                        bufsz = 1024;
                        goto start_recv;
                    case EOT:
                        flushinput();
                        _outbyte(ACK);
                        return len; /* normal end */
                    case CAN:
                        if ((c = _inbyte(DLY_1S)) == CAN) {
                            flushinput();
                            _outbyte(ACK);
                            return -1; /* canceled by remote */
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
            if (trychar == 'C') { trychar = NAK; continue; }
            flushinput();
            _outbyte(CAN);
            _outbyte(CAN);
            _outbyte(CAN);
            return -2; /* sync error */
    
        start_recv:
            if (trychar == 'C') crc = 1;
            trychar = 0;
            p = xbuff;
            *p++ = c;
            for (i = 0;  i < (bufsz+(crc?1:0)+3); ++i) {
                if ((c = _inbyte(DLY_1S)) < 0) goto reject;
                *p++ = c;
            }
    
            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)    {
                    register int count = destsz - len;
                    if (count > bufsz) count = bufsz;
                    if (count > 0) {
                        memcpy (&dest[len], &xbuff[3], count);
                        len += count;
                    }
                    ++packetno;
                    retrans = MAXRETRANS+1;
                }
                if (--retrans <= 0) {
                    flushinput();
                    _outbyte(CAN);
                    _outbyte(CAN);
                    _outbyte(CAN);
                    return -3; /* too many retry error */
                }
                _outbyte(ACK);
                continue;
            }
        reject:
            flushinput();
            _outbyte(NAK);
        }
    }
    
    int xmodemTransmit(unsigned char *src, int srcsz)
    {
        unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
        int bufsz, crc = -1;
        unsigned char packetno = 1;
        int i, c, len = 0;
        int retry;
    
        for(;;) {
            for( retry = 0; retry < 16; ++retry) {
                if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
                    switch (c) {
                    case 'C':
                        crc = 1;
                        goto start_trans;
                    case NAK:
                        crc = 0;
                        goto start_trans;
                    case CAN:
                        if ((c = _inbyte(DLY_1S)) == CAN) {
                            _outbyte(ACK);
                            flushinput();
                            return -1; /* canceled by remote */
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
            _outbyte(CAN);
            _outbyte(CAN);
            _outbyte(CAN);
            flushinput();
            return -2; /* no sync */
    
            for(;;) {
            start_trans:
                xbuff[0] = SOH; bufsz = 128;
                xbuff[1] = packetno;
                xbuff[2] = ~packetno;
                c = srcsz - len;
                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;
                    }
                    else {
                        unsigned char ccks = 0;
                        for (i = 3; i < bufsz+3; ++i) {
                            ccks += xbuff[i];
                        }
                        xbuff[bufsz+3] = ccks;
                    }
                    for (retry = 0; retry < MAXRETRANS; ++retry) {
                        for (i = 0; i < bufsz+4+(crc?1:0); ++i) {
                            _outbyte(xbuff[i]);
                        }
                        if ((c = _inbyte(DLY_1S)) >= 0 ) {
                            switch (c) {
                            case ACK:
                                ++packetno;
                                len += bufsz;
                                goto start_trans;
                            case CAN:
                                if ((c = _inbyte(DLY_1S)) == CAN) {
                                    _outbyte(ACK);
                                    flushinput();
                                    return -1; /* canceled by remote */
                                }
                                break;
                            case NAK:
                            default:
                                break;
                            }
                        }
                    }
                    _outbyte(CAN);
                    _outbyte(CAN);
                    _outbyte(CAN);
                    flushinput();
                    return -4; /* xmit error */
                }
                else {
                    for (retry = 0; retry < 10; ++retry) {
                        _outbyte(EOT);
                        if ((c = _inbyte((DLY_1S)<<1)) == ACK) break;
                    }
                    flushinput();
                    return (c == ACK)?len:-5;
                }
            }
        }
    }
    
    #ifdef TEST_XMODEM_RECEIVE
    int main(void)
    {
        int st;
    
        printf ("Send data using the xmodem protocol from your terminal emulator now...
    ");
        /* the following should be changed for your environment:
           0x30000 is the download address,
           65536 is the maximum size to be written at this address
         */
        st = xmodemReceive((char *)0x30000, 65536);
        if (st < 0) {
            printf ("Xmodem receive error: status: %d
    ", st);
        }
        else  {
            printf ("Xmodem successfully received %d bytes
    ", st);
        }
    
        return 0;
    }
    #endif
    #ifdef TEST_XMODEM_SEND
    int main(void)
    {
        int st;
    
        printf ("Prepare your terminal emulator to receive data now...
    ");
        /* the following should be changed for your environment:
           0x30000 is the download address,
           12000 is the maximum size to be send from this address
         */
        st = xmodemTransmit((char *)0x30000, 12000);
        if (st < 0) {
            printf ("Xmodem transmit error: status: %d
    ", st);
        }
        else  {
            printf ("Xmodem successfully transmitted %d bytes
    ", st);
        }
    
        return 0;
    }
    #endif

     crc16.c

    /*    
     * Copyright 2001-2010 Georges Menie (www.menie.org)
     * All rights reserved.
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *     * Neither the name of the University of California, Berkeley nor the
     *       names of its contributors may be used to endorse or promote products
     *       derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include "crc16.h"
    
    /* CRC16 implementation acording to CCITT standards */
    
    static const unsigned short crc16tab[256]= {
        0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
        0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
        0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
        0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
        0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
        0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
        0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
        0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
        0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
        0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
        0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
        0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
        0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
        0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
        0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
        0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
        0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
        0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
        0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
        0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
        0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
        0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
        0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
        0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
        0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
        0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
        0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
        0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
        0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
        0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
        0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
        0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
    };
      
    unsigned short crc16_ccitt(const void *buf, int len)
    {
        register int counter;
        register unsigned short crc = 0;
        for( counter = 0; counter < len; counter++)
            crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF];
        return crc;
    }

    crc16.h

    /*    
     * Copyright 2001-2010 Georges Menie (www.menie.org)
     * All rights reserved.
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *     * Neither the name of the University of California, Berkeley nor the
     *       names of its contributors may be used to endorse or promote products
     *       derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #ifndef _CRC16_H_
    #define _CRC16_H_
    
    unsigned short crc16_ccitt(const void *buf, int len);
    
    #endif /* _CRC16_H_ */

    附件打包下载

    http://files.cnblogs.com/files/dong1/xmodem.c.zip

  • 相关阅读:
    log4j动态添加appender
    【翻译】java里编写基准测试的一些经验
    java线程池:获取运行线程数并控制线程启动速度
    maven里的mirror和repository: 配置多repository
    使用maven shade plugin 打可执行Jar包
    activemq plugin开发指南及示例
    通过加入classpath的形式实现命令行运行java程序时引入第三方jar包
    java异常、异常处理机制
    内部类
    接口
  • 原文地址:https://www.cnblogs.com/dong1/p/6567949.html
Copyright © 2011-2022 走看看