⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* xmodem.c: * Command to upload or download via XMODEM protocol.  Xmodem is quite * limited, but adequate for simple file up/down load. * This also supports XMODEM-1K and YMODEM.  YMODEM is an extension to XMODEM * that uses a 1K packet size, CRC and the first packet (seqno=0) contains * information about the file being downloaded (in partiuclar, the name). * YMODEM also supports BATCH downloads (multiple files downloaded in one * transaction).  This code supports incoming BATCH downloads (not tested * because I can't find any terminal emulators that do it), but not for  * uploads. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#include "genlib.h"#include "stddefs.h"#include "flash.h"#include "tfs.h"#include "tfsprivate.h"#include "cli.h"#if INCLUDE_XMODEM/* struct xinfo: * Used to contain information pertaining to the current transaction. * The structure is built by the command Xmodem, then passed to the other * support functions (Xup, Xdown, etc..) for reference and update. */struct xinfo {    uchar   sno;            /* Sequence number. */    uchar   pad;            /* Unused, padding. */    int     xfertot;        /* Running total of transfer. */    int     pktlen;         /* Length of packet (128 or 1024). */    int     pktcnt;         /* Running tally of number of packets processed. */    int     filcnt;         /* Number of files transferred by ymodem. */    long    size;           /* Size of upload. */    ulong   flags;          /* Storage for various runtime flags. */    ulong   base;           /* Starting address for data transfer. */    ulong   dataddr;        /* Running address for data transfer. */    int     errcnt;         /* Keep track of errors (used in verify mode). */    char    *firsterrat;    /* Pointer to location of error detected when */                            /* transfer is in verify mode. */    char    fname[TFSNAMESIZE];};/* Runtime flags: */#define USECRC  (1<<0)#define VERIFY  (1<<1)#define YMODEM  (1<<2)/* Current xmodem operation: */#define XNULL   0#define XUP     1#define XDOWN   2/* X/Ymodem protocol: */#define SOH     0x01#define STX     0x02#define EOT     0x04#define ACK     0x06#define NAK     0x15#define CAN     0x18#define ESC     0x1b#define PKTLEN_128  128#define PKTLEN_1K   1024static int Xup(struct xinfo *);static int Xdown(struct xinfo *);static int getPacket(uchar *,struct xinfo *);static int putPacket(uchar *,struct xinfo *);char *XmodemHelp[] = {    "Xmodem file transfer",    "-[a:BdF:f:i:s:t:uvy]",    "Options:",    " -a{##}     address (overrides default of APPRAMBASE)",#if INCLUDE_FLASH    " -B         boot sector reload",#endif    " -c         use crc (default = checksum)",    " -d         download",#if INCLUDE_TFS    " -F{name}   filename",    " -f{flags}  file flags (see tfs)",    " -i{info}   file info (see tfs)",#endif    " -s{##}     size (overrides computed size)",    " -t{##}     address for xmodem trace buffer",    " -u         upload",    " -v         verify only",#if INCLUDE_TFS    " -y         use Ymodem extensions",#endif    "Notes:",    " * Either -d or -u must be specified (-B implies -d).",    " * XMODEM forces a 128-byte modulo on file size.  The -s option",    "   can be used to override this when transferring a file to TFS.",    " * File upload requires no address or size (size will be mod 128).",    " * When using -B, it should be the ONLY command line option,",    "   it's purpose is to reprogram the boot sector, so be careful!",    (char *)0,};intXmodem(int argc,char *argv[]){#if INCLUDE_TFS    TFILE   *tfp;#endif    char    *info, *flags;    struct  xinfo xi;    int opt, xop, newboot;    xop = XNULL;    newboot = 0;    info = (char *)0;    flags = (char *)0;    MtraceInit(0,0);    xi.fname[0] = 0;    xi.size = 0;    xi.flags = 0;    xi.filcnt = 0;    xi.pktlen = PKTLEN_128;    xi.base = xi.dataddr = getAppRamStart();    while ((opt=getopt(argc,argv,"a:Bci:f:dF:ks:t:uvy")) != -1) {        switch(opt) {        case 'a':            xi.dataddr = xi.base = strtoul(optarg,(char **)0,0);            break;        case 'B':            xop = XDOWN;            newboot = 1;            break;        case 'c':            xi.flags |= USECRC;            break;        case 'd':            xop = XDOWN;            break;#if INCLUDE_TFS        case 'F':            strncpy(xi.fname,optarg,TFSNAMESIZE);            break;        case 'f':            flags = optarg;            break;        case 'i':            info = optarg;            break;#endif        case 'k':            xi.pktlen = PKTLEN_1K;            break;        case 's':            xi.size = (ulong)strtoul(optarg,(char **)0,0);            break;        case 't':            MtraceInit((char *)strtoul(optarg,(char **)0,0),99999999);            break;        case 'u':            xop = XUP;            break;        case 'v':            xi.flags |= VERIFY;            break;#if INCLUDE_TFS        case 'y':            xi.flags |= (YMODEM | USECRC);            xi.pktlen = PKTLEN_1K;            break;#endif        default:            return(CMD_PARAM_ERROR);        }    }    /* There should be no arguments after the option list. */    if (argc != optind)        return(CMD_PARAM_ERROR);    if (xop == XUP) {        if ((xi.flags & YMODEM) && !(xi.fname[0]))            printf("Ymodem upload needs filename\n");        else {            if (xi.fname[0]) {  /* Causes -a and -s options to be ignored. */#if INCLUDE_TFS                tfp = tfsstat(xi.fname);                if (!tfp) {                    printf("%s: file not found\n",xi.fname);                    return(CMD_FAILURE);                }                xi.base = xi.dataddr = (ulong)TFS_BASE(tfp);                xi.size = TFS_SIZE(tfp);#endif            }            rawon();            Xup(&xi);            rawoff();        }    }    else if (xop == XDOWN) {        long    tmpsize;        if ((xi.flags & YMODEM) && (xi.fname[0]))            printf("Ymodem download gets name from protocol, '%s' ignored\n",                xi.fname);        rawon();        tmpsize = (long)Xdown(&xi);        rawoff();        if ((!xi.size) || (tmpsize < 0))            xi.size = tmpsize;#if INCLUDE_FLASH#if INCLUDE_TFS        if ((xi.fname[0]) && (xi.size > 0)) {            int err;            printf("Writing to file '%s'...\n",xi.fname);            err = tfsadd(xi.fname,info,flags,(uchar *)xi.base,xi.size);            if (err != TFS_OKAY) {                printf("%s: %s\n",xi.fname,(char *)tfsctrl(TFS_ERRMSG,err,0));                return(CMD_FAILURE);            }        }        else#endif        if ((newboot) && (xi.size > 0)) {            extern  int FlashProtectWindow;            char    *bb;            ulong   bootbase;            bb = getenv("BOOTROMBASE");            if (bb)                bootbase = strtoul(bb,0,0);            else                bootbase = BOOTROM_BASE;            FlashProtectWindow = 1;            printf("Reprogramming boot @ 0x%lx from 0x%lx, %ld bytes.\n",                bootbase,xi.base,xi.size);            if (askuser("OK?")) {                if (flashewrite(&FlashBank[0],(char *)bootbase,                  (char *)xi.base,xi.size) == -1) {                    printf("failed\n");                    return(CMD_FAILURE);                }            }        }#endif    }    else        return(CMD_PARAM_ERROR);    return(CMD_SUCCESS);}/* putPacket(): * Used by Xup to send packets. */static intputPacket(uchar *tmppkt, struct xinfo *xip){    int     c, i;    uchar   *cp;    ushort  chksm;    cp = (uchar *)&chksm;    chksm = 0;        if (xip->pktlen == PKTLEN_128)        rputchar(SOH);    else        rputchar(STX);    rputchar(xip->sno);    rputchar((uchar)~(xip->sno));    if (xip->flags & USECRC) {        for(i=0;i<xip->pktlen;i++) {            rputchar(*tmppkt);            chksm = (chksm<<8)^xcrc16tab[(chksm>>8)^*tmppkt++];        }        /* An "endian independent way to extract the CRC bytes. */        rputchar((char)(chksm >> 8));        rputchar((char)chksm);    }    else {        for(i=0;i<xip->pktlen;i++) {            rputchar(*tmppkt);            chksm = ((chksm+*tmppkt++)&0xff);        }        rputchar((uchar)(chksm&0x00ff));    }    c = getchar();          /* Wait for ack */    /* If pktcnt == -1, then this is the first packet sent by     * YMODEM (filename) and we must wait for one additional     * character in the response.     */    if (xip->pktcnt == -1)        c = getchar();    return(c);}/* getPacket(): * Used by Xdown to retrieve packets. */static intgetPacket(uchar *tmppkt, struct xinfo *xip)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -