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

📄 ian_xmodem.c

📁 MIPS架构Xmodem和Ymodem源码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * 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)",	" -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;	/* Parse command line arguments */	while ((opt=getopt(argc,argv,"a:Bci:f:dF:ks: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 '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;			if (fname && fname[0]) {				strcpy(yif.fname[0], fname);			} else {				strcpy(yif.fname[0], "noname");			}			yif.size[0] = size;#if ! INCLUDE_TFS			if ( yif.size[0] <= 0 ) {				printf("%s\n", xerr_msg(XERR_NOSIZE));				return(CMD_FAILURE);			}#endif			r = Yup(&yif);			printf("\n");			if ( yif.filecnt > 0 ) {				printf("Sent %d file%s.\n",					   yif.filecnt, (yif.filecnt > 1) ? "s" : "");				for (i = 0; i < yif.filecnt; i++) {					printf(" %s: %ld bytes, %ld blocks, @ 0x%08lx\n",						   yif.fname[i] ? yif.fname[i] : "<noname>",						   yif.size[i],						   yif.pktcnt[i],						   yif.dataddr[i]);				}			}			if ( r < 0 ) {				printf("%s\n", xerr_msg(r));				return(CMD_FAILURE);			}					} else {			/* plain X-modem */			xif.dataddr = dataddr;			xif.size = size;			xif.onek = onek;			if ( fname && fname[0] ) {#if INCLUDE_TFS				if ( ! (tfp = tfsstat(fname)) ) {					printf("%s\n", xerr_msg(XERR_NOFILE));					return(CMD_FAILURE);				}				memcpy((char *)(xif.dataddr), TFS_BASE(tfp), tfp->filsize);				xif.size = size = tfp->filsize;#endif			}			if ( xif.size <= 0 ) {				printf("%s\n", xerr_msg(XERR_NOSIZE));				return(CMD_FAILURE);			}			r = Xup(&xif, XMODEM);			printf("\n");			if ( r < 0 ) {				printf("%s\n", xerr_msg(r));				return(CMD_FAILURE);			}			printf("Sent 1 file.\n");			printf(" %s: %ld bytes, %d blocks, @ 0x%08lx\n",				   fname[0] ? fname : "<no-name>",				   xif.size,				   xif.pktcnt,				   xif.dataddr);		}	} else if ( xop == XDOWN ) {		/* DOWNLOAD: Host --> Micromonitor */		if ( ymodem ) {			/* Use Y-Modem extensions */			yif.baseaddr = dataddr;			yif.usecrc = !usecrc;			yif.verify = verify;			yif.flags = flags;			yif.info = info;			r = Ydown(&yif);			printf("\n");			if ( yif.filecnt ) {				printf("Rcvd %d file%s.\n",					   yif.filecnt, (yif.filecnt > 1) ? "s" : "");				if ( yif.verify ) {					for (i = 0; i < yif.filecnt; i++) {						printf(" %s: %ld bytes, %ld blocks, %ld errors, " 							   "first err @ 0x%08lx\n",							   yif.fname[i] ? yif.fname[i] : "<noname>",							   yif.size[i],							   yif.pktcnt[i],							   yif.errcnt[i], yif.firsterrat[i]);					}				} else {					for (i = 0; i < yif.filecnt; i++) {						printf(" %s: %ld bytes, %ld blocks, @ 0x%08lx\n",							   yif.fname[i] ? yif.fname[i] : "<noname>",							   yif.size[i],							   yif.pktcnt[i],							   yif.dataddr[i]);					}				}			}			if ( r < 0 ) {				if ( r == XERR_TFS ) {					printf("%s: %s: %s\n",						   xerr_msg(XERR_TFS),						   yif.fname[yif.filecnt], 						   (char *)tfsctrl(TFS_ERRMSG,tfserr,0));				} else {					printf("%s\n", xerr_msg(r));				}				return(CMD_FAILURE);			}		} else {			/* plain X-Modem */			xif.dataddr = dataddr;			xif.usecrc = usecrc;			xif.verify = verify;			if (verify && fname && fname[0]) {#if INCLUDE_TFS				if (! (tfp = tfsstat(fname)) ) {

⌨️ 快捷键说明

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