📄 xmodem.c
字号:
/*#include "flash.h"#include "tfs.h"#include "tfsprivate.h"#include "ether.h"*/#include "genlib.h" //strtoul getopt#include "config.h" #include "cli.h" static char *(*_getenv)();/*mon_getenv for getenv from monlib.c*/char * mon_getenv(char *name){ char *ret; ret = _getenv(name); return(ret);}/*getenv for getappramstart from newlib_hooks.c*/char * getenv(const char *name){ return(mon_getenv((char *)name));}/*APPLICATION_RAMSTART for getappramstart from start.c */#ifdef APPRAMBASE_OVERRIDE APPLICATION_RAMSTART = APPRAMBASE_OVERRIDE;#else APPLICATION_RAMSTART = (((unsigned long)&bss_end) | 0xfff) + 1;#endif/*getappramstart for xmodem*/unsigned long getAppRamStart(void){ char *apprambase; unsigned long value; apprambase = getenv("APPRAMBASE"); if (apprambase) value = strtoul(apprambase,0,0); else value = APPLICATION_RAMSTART; return(value);}/* 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 { unsigned char sno; /* Sequence number. */ unsigned char 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. */ unsigned long flags; /* Storage for various runtime flags. */ unsigned long base; /* Starting address for data transfer. */ unsigned long dataddr; /* Running address for data transfer. */ int errcnt; /* Keep track of errors (used in verify mode). */ //int nakresend; /* Time between each NAK sent at Xdown startup. */ char *firsterrat; /* Pointer to location of error detected when */ /* transfer is in verify mode. */ char fname[TFSNAMESIZE];};/* Runtime flags: */#define USECRC (1<<0) //0001 #define VERIFY (1<<1) //0010#define YMODEM (1<<2) //0100/* Current xmodem operation: */#define XNULL 0#define XUP 1#define XDOWN 2/* X/Ymodem protocol: */#define SOH 0x01 //00000001#define STX 0x02 //00000010#define EOT 0x04 //00000100#define ACK 0x06 //00000110#define NAK 0x15 //00010101#define CAN 0x18 //00011000#define ESC 0x1b //00011011#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: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)", " -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,};int Xmodem(int argc,char *argv[]){/*#if INCLUDE_TFS TFILE *tfp;#endif*/ char *info, *flags; struct xinfo xi; int opt, xop, newboot;/* #if INCLUDE_ETHERNET int eon;#endif*/ xop = XNULL; newboot = 0; info = (char *)0; flags = (char *)0; xi.fname[0] = 0; xi.size = 0; xi.flags = 0; xi.filcnt = 0; xi.nakresend = 12; xi.pktlen = PKTLEN_128; xi.base = xi.dataddr = getAppRamStart(); while ((opt=getopt(argc,argv,"a:Bci:f:dF:ks: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': xi.nakresend -= 2; /* -ddd decreases Xdown() resend delay */ 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 = (unsigned long)strtoul(optarg,(char **)0,0); 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();/*#ifdef DONT_DISABLE_ENET_IN_XMODEM // See note at top of file Xup(&xi);#else #if INCLUDE_ETHERNET eon = DisableEthernet(); #endif Xup(&xi); #if INCLUDE_ETHERNET if (eon) EthernetStartup(0,0); #endif#endif*/ 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();/*#ifdef DONT_DISABLE_ENET_IN_XMODEM // See note at top of file tmpsize = (long)Xdown(&xi);#else #if INCLUDE_ETHERNET eon = DisableEthernet(); #endif tmpsize = (long)Xdown(&xi); #if INCLUDE_ETHERNET if (eon) EthernetStartup(0,0); #endif#endif*/ 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(addrtobank((char *)bootbase),(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 int putPacket(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 = test_getchar(); /* Wait for ack */ /* If pktcnt == -1, then this is the first packet sent by * YMODEM (filename) and we must wait for one additional
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -