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

📄 ian_xmodem.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * ian_xmodem.c * * X and Y modem file download and upload protocols. * * by Nick Patavalis (npat@inaccessnetworks.com) * *  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 * * $Id: ian_xmodem.c,v 1.6 2001/07/16 15:19:55 npat Exp $ *//***************************************************************************/#include "config.h"#include "genlib.h"#include "stddefs.h"#include "flash.h"#include "tfs.h"#include "tfsprivate.h"#include "cli.h"#include "ascii.h"/***************************************************************************/#if INCLUDE_XMODEM/* These "wait" functions may be better placed in chario.c.  They * are here for now, because this version of xmodem is the only * module that uses them. */intwaitchar(int tmo){    int timeout;    int rval;    timeout = tmo * LoopsPerSecond;    while(!gotachar() && timeout)        timeout--;    if (timeout)        rval = getchar();    else        rval = -1;    return(rval);}voidwaitclear (void){    ulong timeout;    while (1) {        timeout = 1 * LoopsPerSecond;        while(!gotachar() && timeout)            timeout--;        if (!timeout)            break;        getchar();    }}intwaitbytes (char *buf, int cnt, int tmo){    ulong timeout;    int i;    for(i=0; i<cnt; i++) {        timeout = tmo * LoopsPerSecond;        while(!gotachar() && timeout)            timeout--;        if (!timeout)            break;        buf[i] = (char)getchar();    }    return (i < cnt) ? -1 : i;}char ian_xmodem_cvsid[] = "$Id: ian_xmodem.c,v 1.6 2001/07/16 15:19:55 npat Exp $";/***************************************************************************//* RCV: Frame timeout. Time to wait for next frame, before sending a NAK */#define FRAME_TMO  5/* RCV: Character timeout. Characters in the same frame should normally    not be more than CHAR_TMO seconds appart */#define CHAR_TMO   1/* TRN: Transmiter timeout. Usually a large value. The standard suggests    something in the order of 1m */#define TRANS_TMO  20/* TRN: Number of times to retransmit a frame before quiting */#define RETR_MAX   10/* TRN: Number of invalid characters (i.e. not ACK or NAK) received    by the transmiter before quiting. This *not* the right way to do    things. The right way is to wait for a valid char up to TRANS_TMO    secs, and then quit. Unfortunatelly without timers, this behavior is    a bit tricky to implement. So this crude approxomation will have to do    for the moment. */#define NOISE_MAX 100/* Maximum number of files per Y-modem transfer */#define YFILES_MAX 10/***************************************************************************//* X/Ymodem protocol: */#define SOH ASCII_SOH#define STX ASCII_STX#define EOT ASCII_EOT#define ACK ASCII_ACK#define NAK ASCII_NAK#define CAN ASCII_CAN#define ESC ASCII_ESC#define BS  ASCII_BS#define PKTLEN_128 128#define PKTLEN_1K  1024/***************************************************************************/enum _xmodem_ops {    XNULL = 0,    XUP,    XDOWN};enum _protocol_type {    XMODEM = 0,    YMODEM = 1};#define XERR_GEN  (-1)#define XERR_TOUT (-2)#define XERR_SYNC (-3)#define XERR_CAN  (-4)#define XERR_UCAN (-5)#define XERR_RETR (-6)#define XERR_HEAD (-7)#define XERR_TFS  (-8)#define XERR_NOFILE (-9)#define XERR_NOSIZE (-10)static char *xerr_msgs[] = {    "E00:No Error",    "E01:General Error",    "E02:Timeout",    "E03:Synchronization error",    "E04:Operation canceled",    "E05:Operation canceled by user",    "E06:Maximum retransmitions exceeded",    "E07:Invalid header-block",    "E08:TFS error",    "E09:File not found",    "E10:Cannot determine file size"};/***************************************************************************//* struct yinfo: * used to pass information to and from the y-modem transfer functions. */struct yinfo {      int usecrc;      /* use 16bit CRC instead of 8bit checksum */    int onek;        /* use 1k blocks instead of 128bytes blocks */     int verify;      /* operate in verification-mode */    ulong baseaddr;  /* start address for the first file data transfer */    char *flags;     /* TFS file flags (same for all files) */    char *info;      /* TFS file info (same for all files) */    int filecnt;                         /* number of files processed */    char fname[YFILES_MAX][TFSNAMESIZE]; /* names of files processed */    ulong dataddr[YFILES_MAX];           /* start address of each file */    long size[YFILES_MAX];               /* size of each file in bytes */    long pktcnt[YFILES_MAX];             /* number of frames exchanged */    long errcnt[YFILES_MAX];             /* number of verification errors */    ulong firsterrat[YFILES_MAX];        /* offset of first error */};/* struct xinfo: * used to pass information to and from the x-modem transfer functions. */struct xinfo {    int     usecrc;      /* use 16bit CRC instead of 8bit checksum */    int     onek;        /* use 1k blocks instead of 128bytes blocks */     int     verify;      /* operate in verification-mode */    ulong   dataddr;     /* start address for data transfer */    long    size;        /* size of the tansfer in bytes */    int     pktcnt;      /* number of packets processed */    int     errcnt;      /* number of errors (used in verify mode) */    ulong   firsterrat;  /* pointer to location if first error (vrf mode) */};/***************************************************************************//* local prototypes */static int Xup(struct xinfo *, int);static int Xdown(struct xinfo *, int);static int Ydown(struct yinfo *);static int Yup(struct yinfo *);static int getPacket(uchar *, int, int);static void putPacket (uchar *, int, int, int);static char *xerr_msg(int);static void doCAN(void);/***************************************************************************//* Defined globaly to conserve stack-space. Ugly but effective. */static struct yinfo yif;static struct xinfo xif;static uchar pktbuff[PKTLEN_1K];/* Used to pass-back the TFS error code, in case of a TFS error */int tfserr;/***************************************************************************/char *XmodemHelp[] = {    "X/Y modem file transfer",#if INCLUDE_TFS#if INCLUDE_FLASH    "-[a:BckdF:f:i:s:t:uvy]",#else /* of INCLUDE_FLASH */    "-[a:ckdF:f:i:s:t:uvy]",#endif /* of INCLUDE_FLASH */#else /* of INCLUDE_TFS */#if INCLUDE_FLASH    "-[a:Bckds:t:uvy]",#else /* of INCLUDE_FLASH */    "-[a:ckds:t:uvy]",#endif /* of INCLUDE_FLASH */#endif /* of INCLUDE_TFS */    "Options:",    " -a{##}     address (overrides default of APPRAMBASE)",#if INCLUDE_FLASH    " -B         Program boot-sector (i.e. uMon-binary reload)",#endif    " -c         have xmodem receiver request the use of CRC (def = chksum)",    "            have ymodem receiver request the use of chksum (def = CRC)",    " -k         send 1K frames (default = 128bytes)",    " -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",    " -y         use YMODEM extensions",    "Notes:",    " * Either -d or -u must be specified (-B implies -d).",    " * The -c argument affects only the receiver (download operations).",    "   The -k option affects only the transmitter (upload operations).",#if INCLUDE_TFS    " * YMODEM downloads: The file-name and size arguments are ignored,",    "   since they are supplied by the sender. Multiple files can be",    "   downloaded. Each file is downloaded at the address specified by",    "   the '-a' argument (or at APPRAMBASE), and then saved to the TFS.",    "   A summary of the files downloaded, their sizes and the download",    "   locations is displayed at the end of the transfer.", #else /* of INCLUDE_TFS */    " * YMODEM downloads: The file-name and size arguments are ignored,",    "   since they are supplied by the sender. Multiple files can be",    "   downloaded. The files are stored sequencially starting at the",     "   address specified with '-a' (or at APPRAMBASE). A summary of the",    "   files downloaded, their sizes and the download locations is",    "   displayed at the end of the transfer.",#endif /* of INCLUDE_TFS */#if INCLUDE_FLASH    "   If -B is given, the boot-sector is programmed with the contents",    "   of the last file downloaded.",#endif#if INCLUDE_TFS    " * XMODEM downloads: Only one file can be downloaded. A 128-byte",    "   modulo is forced on file size. The file is downloaded at the address",    "   specified by '-a' (or at APPRAMBASE), and then saved to a TFS file",    "   if a file-name argument is given. The '-s' option can be used to",     "   override the 128-bytes modulo when transferring a file to TFS.",#else /* of INCLUDE_TFS */    " * XMODEM downloads: Only one file can be downloaded. A 128-byte",    "   modulo is forced on file size. The file is downloaded at the address",    "   specified by '-a' (or at APPRAMBASE).",#endif /* of INCLUDE_TFS */#if INCLUDE_FLASH    "   If -B is given, the boot-sector is programmed with the contents",    "   of the downloaded file.",#endif /* of INCLUDE_FLASH */#if INCLUDE_TFS    " * X/YMODEM uploads: Only one file can be uploaded. The size argument",    "   is ignored since it is taken form the TFS. Before the file is",     "   uploaded it is copied at the address specified by '-a' (or at",     "   APPRAMBASE).",#else /* of INCLUDE_TFS */    " * X/YMODEM uploads: Only one file can be uploaded. The size argument",    "   is mandatory (since there is no other way to know the number of",     "   bytes to transfer). The data (file) to be uploaded are taken form",    "   the address specified by '-a' (or from APPRAMBASE).",#endif /* of INCLUDE_TFS */    (char *)0,};/***************************************************************************/intXmodem(int argc,char *argv[]){#if INCLUDE_TFS    TFILE   *tfp;#endif    char fname[TFSNAMESIZE+1], *info, *flags;    int opt, xop, newboot, usecrc, verify, onek, ymodem;    ulong dataddr;    long size;    int i, r;    /* Initialize to defaults */    dataddr = getAppRamStart();    xop = XNULL;    newboot = 0;    usecrc = 0;    fname[0]='\0';    info = (char *)0;    flags = (char *)0;    onek = 0;    size = 0;    verify = 0;    ymodem = 0;    MtraceInit(0,0);    /* Parse command line arguments */    while ((opt=getopt(argc,argv,"a:Bci:f:dF:ks:t:uvy")) != -1) {        switch(opt) {        case 'a':            dataddr = strtoul(optarg,(char **)0,0);            break;#if INCLUDE_FLASH        case 'B':            xop = XDOWN;            newboot = 1;            break;#endif        case 'c':            usecrc = 1;            break;        case 'd':            xop = XDOWN;            break;#if INCLUDE_TFS        case 'F':            strncpy(fname, optarg, TFSNAMESIZE);            break;        case 'f':            flags = optarg;            break;        case 'i':            info = optarg;            break;#endif        case 'k':            onek = 1;            break;        case 's':            size = (ulong)strtoul(optarg,(char **)0,0);            break;        case 't':            MtraceInit((char *)strtoul(optarg,(char **)0,0),9999999);            break;        case 'u':            xop = XUP;            break;        case 'v':            verify = 1;            break;        case 'y':            ymodem = 1;            break;        default:            return(CMD_PARAM_ERROR);        }    }    /* There should be no arguments after the option list. */    if (argc != optind)        return(CMD_PARAM_ERROR);    if ( xop == XUP ) {        /* UPLOAD: Host <-- Micromonitor */        if ( ymodem ) {            /* we 're using the Y-Modem extensions */            yif.onek = onek;            yif.baseaddr = dataddr;            yif.filecnt = 1;

⌨️ 快捷键说明

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