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

📄 nindy.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Bad checksum: report, send NAK, and re-receive		 */		fprintf(stderr, errfmt, cs_recv, cs_calc );		write (nindy_fd, "-", 1);	}}/****************************************************************************** * putpkt: *	Send a packet to NINDY, checksumming it and converting special *	characters to escape sequences. ******************************************************************************//* This macro puts the character 'c' into the buffer pointed at by 'p', * and increments the pointer.  If 'c' is one of the 4 special characters * in the transmission protocol, it is converted into a 2-character * escape sequence. */#define PUTBUF(c,p)						\	if ( c == DLE || c == ESC || c == XON || c == XOFF ){	\		*p++ = ESC;					\		*p++ = c | 0x40;				\	} else {						\		*p++ = c;					\	}staticputpkt( msg, len )    unsigned char *msg;	/* Command to be sent, without lead ^P (\020) or checksum */    int len;	/* Number of bytes in message			*/{	static char *buf = NULL;/* Local buffer -- build packet here	*/	static int maxbuf = 0;	/* Current length of buffer		*/	unsigned char ack;	/* Response received from NINDY		*/	unsigned char checksum;	/* Packet checksum			*/	char *p;		/* Pointer into buffer			*/	int lenhi, lenlo; 	/* High and low bytes of message length	*/	int i;	/* Make sure local buffer is big enough.  Must include space for	 * packet length, message body, and checksum.  And in the worst	 * case, each character would expand into a 2-character escape	 * sequence.	 */	if ( maxbuf < ((2*len)+10) ){		if ( buf ){			free( buf );		}		buf = malloc( maxbuf=((2*len)+10) );	}	/* Attention, NINDY!	 */	write( nindy_fd, "\020", 1 );	lenlo = len & 0xff;	lenhi = (len>>8) & 0xff;	checksum = lenlo + lenhi;	p = buf;	PUTBUF( lenlo, p );	PUTBUF( lenhi, p );	for ( i=0; i<len; i++ ){		PUTBUF( msg[i], p );		checksum += msg[i];	}	PUTBUF( checksum, p );	/* Send checksummed message over and over until we get a positive ack	 */	write( nindy_fd, buf, p-buf );	while (1){		if ( !rdnin(&ack,1,5) ){			/* timed out */			fprintf(stderr,"ACK timed out; resending\r\n");			write(nindy_fd,"\020",1);/* Attention, NINDY! */			write( nindy_fd, buf, p-buf );		} else if ( ack == '+' ){			return;		} else if ( ack == '-' ){			fprintf( stderr, "Remote NAK; resending\r\n" );			write( nindy_fd, buf, p-buf );		} else {			fprintf( stderr, "Bad ACK, ignored: <%c>\r\n", ack );		}	}}/****************************************************************************** * send: *	Send a message to a remote NINDY.  Check message status byte *	for error responses.  If no error, return NINDY reponse (if any). ******************************************************************************/staticsend( out, len, in )    unsigned char *out;	/* Message to be sent to NINDY			*/    int len;		/* Number of meaningful bytes in out buffer	*/    unsigned char *in;	/* Where to put response received from NINDY	*/{	char *fmt;	int status;	static char *errmsg[] = {		"",						/* 0 */		"Buffer overflow",				/* 1 */		"Unknown command",				/* 2 */		"Wrong amount of data to load register(s)",	/* 3 */		"Missing command argument(s)",			/* 4 */		"Odd number of digits sent to load memory",	/* 5 */		"Unknown register name",			/* 6 */		"No such memory segment",			/* 7 */		"No breakpoint available",			/* 8 */		"Can't set requested baud rate",		/* 9 */	};#	define NUMERRS	( sizeof(errmsg) / sizeof(errmsg[0]) )	static char err1[] = "Unknown error response from NINDY: #%d\r\n";	static char err2[] = "Error response #%d from NINDY: %s\r\n";	while (1){		putpkt(out,len);		status = getpkt(in);		if ( status == TIMEOUT ){			fprintf( stderr, "Response timed out; resending\r\n" );		} else {			break;		}	}	if ( status ){		fmt =  status > NUMERRS ? err1 : err2;		fprintf( stderr, fmt, status, errmsg[status] );		abort();	}}		/************************		 *                      *		 *  BAUD RATE ROUTINES  *		 *                      *		 ************************//* Table of baudrates known to be acceptable to NINDY.  Each baud rate * appears both as character string and as a Unix baud rate constant. */struct baudrate {	char *string;	int rate;};static struct baudrate baudtab[] = {	 "1200", B1200,	 "2400", B2400,	 "4800", B4800,	 "9600", B9600,	"19200", B19200,	"38400", B38400,	NULL,    0		/* End of table */}; /****************************************************************************** * parse_baudrate: *	Look up the passed baud rate in the baudrate table.  If found, change *	our internal record of the current baud rate, but don't do anything *	about the tty just now. * *	Return pointer to baudrate structure on success, NULL on failure. ******************************************************************************/staticstruct baudrate *parse_baudrate(s)    char *s;	/* Desired baud rate, as an ASCII (decimal) string */{	int i;	for ( i=0; baudtab[i].string != NULL; i++ ){		if ( !strcmp(baudtab[i].string,s) ){			return &baudtab[i];		}	}	return NULL;}/****************************************************************************** * try_baudrate: *	Try speaking to NINDY via the specified file descriptor at the *	specified baudrate.  Assume success if we can send an empty command *	with a bogus checksum and receive a NAK (response of '-') back within *	one second. * *	Return 1 on success, 0 on failure. ******************************************************************************/static inttry_baudrate( fd, brp )    int fd;    struct baudrate *brp;{	TTY_STRUCT tty;	unsigned char c;		/* Set specified baud rate and flush all pending input */	ioctl( fd, TIOCGETP, &tty );	TTY_REMOTE( tty, brp->rate );	ioctl( fd, TIOCSETP, &tty );	tty_flush( fd );	/* Send empty command with bad checksum, hope for NAK ('-') response */	write( fd, "\020\0\0\001", 4 );	if ( !rdnin(&c,1,1) ){		/* timed out */		return 0;	} else {		return (c == '-');	}}/****************************************************************************** * autobaud: *	Get NINDY talking over the specified file descriptor at the specified *	baud rate.  First see if NINDY's already talking at 'baudrate'.  If *	not, run through all the legal baudrates in 'baudtab' until one works, *	and then tell NINDY to talk at 'baudrate' instead. ******************************************************************************/staticautobaud( fd, brp )    int fd;    struct baudrate *brp;{	int i;	TTY_STRUCT tty;	int failures;	say("NINDY at wrong baud rate? Trying to autobaud...\n");	failures = i = 0;	while ( 1 ){		say( "\r%s...   ", baudtab[i].string );		if ( try_baudrate(fd, &baudtab[i]) ){			break;		}		if ( baudtab[++i].string == NULL ){			/* End of table -- wraparound */			i = 0;			if ( failures++ ){				say("\nAutobaud failed again.  Giving up.\n");				exit(1);			} else {				say("\nAutobaud failed. Trying again...\n");			}		}	}	/* Found NINDY's current baud rate;  now change it.	 */	say("Changing NINDY baudrate to %s\n", brp->string);	ninBaud( brp->string );	/* Change our baud rate back to rate to which we just set NINDY.	 */	ioctl( fd, TIOCGETP, &tty );	TTY_REMOTE( tty, brp->rate );	ioctl( fd, TIOCSETP, &tty );}/***************************************************************************** * coffstrip: *	Passed the name of an executable object file in either b.out or *	COFF format. * *	If the file is in b.out format, it is converted to little-endian *	COFF format (i.e., the format suitable for downloading to NINDY). *	In either case, the COFF file is then stripped of all relocation *	and symbol information, to speed up its download. * * RETURNS: *	pointer to the name of the stripped COFF file (a tmp file that has *	been created and closed); NULL on error. *****************************************************************************/#if 0#define STRIP	"bfd_strip"	/* Name of bfd strip utility	*/#endif#define NINDY_OBJ	"coff-Intel-little"char *coffstrip( fn )    char *fn;	/* Name of object file */{	extern char *mktemp();	static char template[] = "/tmp/commXXXXXX";	static char newfile[sizeof template];	char *strip;	/* Pointer to full pathname of strip utility	*/	int success;	/* Return value					*/	int pid;	/* Process ID of xmodem transfer utility	*/	WAITTYPE w;	/* xmodem transfer completion status		*/	int wret;	/* Value returned by wait			*/	char *tempfile;	/* Stripped copy of object file			*/	char buf[400];	strcpy (newfile, template);	tempfile = mktemp( newfile );#if 0	/* Make sure the strip utility is findable.	 */	if ( ((strip = exists("G960BIN",STRIP,NULL,NULL,1)) == NULL)	&&   ((strip = exists("G960BASE","bin",STRIP, NULL,1)) == NULL)#ifdef HOST	&&   ((strip = exists(DEFAULT_BASE,HOST,"bin",STRIP,0)) == NULL)#endif	){		fprintf(stderr,"Can't find '%s' utility\n",STRIP);		fprintf(stderr,"Check env variables G960BIN and G960BASE\n");		return NULL;	}#endif	success = 0;	sprintf( buf, "cp %s %s", fn, tempfile );	printf ("%s\n", buf);	if ( system(buf) == 0 ){		sprintf(buf, "%s -d %s %s", STRIP, NINDY_OBJ, tempfile);		printf ("%s\n", buf);		if ( system(buf) == 0 ){			return tempfile;		}	}	return NULL;}		/**********************************		 *				  *		 *   NINDY INTERFACE ROUTINES	  *		 *                            	  *		 * ninConnect *MUST* be the first *		 * one of these routines called.  *		 **********************************//****************************************************************************** * ninBaud: *	Ask NINDY to change the baud rate on its serial port. *	Assumes we know the baud rate at which NINDY's currently talking. ******************************************************************************/ninBaud( baudrate )    char *baudrate;	/* Desired baud rate, as a string of ASCII decimal			 * digits.			 */{	unsigned char msg[100];	if ( old_nindy ){		OninBaud( baudrate );		return;	}	tty_flush( nindy_fd );	/* Can't use "send" because NINDY reply will be unreadable after	 * baud rate change.	 */	sprintf( msg, "z%s", baudrate );	putpkt( msg, strlen(msg)+1 );	/* "+1" to send terminator too */}/****************************************************************************** * ninBptDel: *	Ask NINDY to delete the specified type of *hardware* breakpoint at *	the specified address.  If the 'addr' is -1, all breakpoints of *	the specified type are deleted. ******************************************************************************/ninBptDel( addr, type )    long addr;	/* Address in 960 memory	*/    char type;	/* 'd' => data bkpt, 'i' => instruction breakpoint */{	unsigned char buf[10];	if ( old_nindy ){		OninBptDel( addr, type == 'd' ? 1 : 0 );		return;	}	buf[0] = 'b';	buf[1] = type;	if ( addr == -1 ){		send( buf, 2, NULL );	} else {		put_int( &buf[2], addr );		send( buf, 6, NULL );	}}/****************************************************************************** * ninBptSet: *	Ask NINDY to set the specified type of *hardware* breakpoint at *	the specified address. ******************************************************************************/ninBptSet( addr, type )    long addr;	/* Address in 960 memory	*/    char type;	/* 'd' => data bkpt, 'i' => instruction breakpoint */{	unsigned char buf[10];	if ( old_nindy ){		OninBptSet( addr, type == 'd' ? 1 : 0 );		return;	}	buf[0] = 'B';	buf[1] = type;	put_int( &buf[2], addr );	send( buf, 6, NULL );}/****************************************************************************** * ninConnect: *	Open the specified tty.  Get communications working at the specified *	baud rate.  Flush any pending I/O on the tty. * *	Return the file descriptor, or -1 on failure. ******************************************************************************/intninConnect( name, baudrate, brk, silent, old_protocol )    char *name;		/* "/dev/ttyXX" to be opened			*/    char *baudrate;/* baud rate: a string of ascii decimal digits (eg,"9600")*/    int brk;		/* 1 => send break to tty first thing after opening it*/    int silent;		/* 1 => stifle unnecessary messages when talking to 			 *	this tty.			 */    int old_protocol;{	int i;	char *p;	struct baudrate *brp;	/* We will try each of the following paths when trying to open the tty	 */	static char *prefix[] = { "", "/dev/", "/dev/tty", NULL };	if ( old_protocol ){		old_nindy = 1;		return OninConnect( name, baudrate, brk, silent );	}	quiet = silent;		/* Make global to this file */	for ( i=0; prefix[i] != NULL; i++ ){		p = malloc(strlen(prefix[i]) + strlen(name) + 1 );		strcpy( p, prefix[i] );		strcat( p, name );		nindy_fd = open(p,O_RDWR);		if ( nindy_fd >= 0 ){#ifdef TIOCEXCL			/* Exclusive use mode (hp9000 does not support it) */			ioctl(nindy_fd,TIOCEXCL,NULL);#endif			if ( brk ){				send_break( nindy_fd );			}			brp = parse_baudrate( baudrate );			if ( brp == NULL ){				say("Illegal baudrate %s ignored; using 9600\n",								baudrate);				brp = parse_baudrate( "9600" );			}			if ( !try_baudrate(nindy_fd,brp) ){				autobaud(nindy_fd,brp);			}			tty_flush( nindy_fd );			say( "Connected to %s\n", p );			free(p);			break;

⌨️ 快捷键说明

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