Exemplo n.º 1
0
void
loop(void)
{
	enum {
		ST_COMMAND,
		ST_TRANSPARENT
	} state;
	int dtr_up;
	fd_set rdset, wrset;
	int newbaud, newflow, newparity, newbits;
	char *newflow_str, *newparity_str;
	char fname[128];
	int r, n;
	unsigned char c;


	tty_q.len = 0;
	state = ST_TRANSPARENT;
	dtr_up = 0;

	for (;;) {
		FD_ZERO(&rdset);
		FD_ZERO(&wrset);
		FD_SET(STI, &rdset);
		FD_SET(tty_fd, &rdset);
		if ( tty_q.len ) FD_SET(tty_fd, &wrset);

		if (select(FD_SETSIZE, &rdset, &wrset, NULL, NULL) < 0)
			fatal("select failed: %d : %s", errno, strerror(errno));

		if ( FD_ISSET(STI, &rdset) ) {

			/* read from terminal */

			do {
				n = read(STI, &c, 1);
			} while (n < 0 && errno == EINTR);
			if (n == 0)
				fatal("stdin closed");
			else if (n < 0)
				fatal("read from stdin failed: %s", strerror(errno));

			switch (state) {

			case ST_COMMAND:
				if ( c == opts.escape ) {
					state = ST_TRANSPARENT;
					/* pass the escape character down */
					if (tty_q.len <= TTY_Q_SZ)
						tty_q.buff[tty_q.len++] = c;
					else
						fd_printf(STO, "\x07");
					break;
				}
				state = ST_TRANSPARENT;
				switch (c) {
				case KEY_EXIT:
					return;
				case KEY_QUIT:
					term_set_hupcl(tty_fd, 0);
					term_flush(tty_fd);
					term_apply(tty_fd);
					term_erase(tty_fd);
					return;
				case KEY_STATUS:
					fd_printf(STO, "\r\n");
					fd_printf(STO, "*** baud: %d\r\n", opts.baud);
					fd_printf(STO, "*** flow: %s\r\n", opts.flow_str);
					fd_printf(STO, "*** parity: %s\r\n", opts.parity_str);
					fd_printf(STO, "*** databits: %d\r\n", opts.databits);
					fd_printf(STO, "*** dtr: %s\r\n", dtr_up ? "up" : "down");
					break;
				case KEY_PULSE:
					fd_printf(STO, "\r\n*** pulse DTR ***\r\n");
					if ( term_pulse_dtr(tty_fd) < 0 )
						fd_printf(STO, "*** FAILED\r\n");
					break;
				case KEY_TOGGLE:
					if ( dtr_up )
						r = term_lower_dtr(tty_fd);
					else
						r = term_raise_dtr(tty_fd);
					if ( r >= 0 ) dtr_up = ! dtr_up;
					fd_printf(STO, "\r\n*** DTR: %s ***\r\n", 
							  dtr_up ? "up" : "down");
					break;
				case KEY_BAUD_UP:
					newbaud = baud_up(opts.baud);
					term_set_baudrate(tty_fd, newbaud);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.baud = newbaud;
					fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
					break;
				case KEY_BAUD_DN:
					newbaud = baud_down(opts.baud);
					term_set_baudrate(tty_fd, newbaud);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.baud = newbaud;
					fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
					break;
				case KEY_FLOW:
					newflow = flow_next(opts.flow, &newflow_str);
					term_set_flowcntrl(tty_fd, newflow);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) {
						opts.flow = newflow;
						opts.flow_str = newflow_str;
					}
					fd_printf(STO, "\r\n*** flow: %s ***\r\n", opts.flow_str);
					break;
				case KEY_PARITY:
					newparity = parity_next(opts.parity, &newparity_str);
					term_set_parity(tty_fd, newparity);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) {
						opts.parity = newparity;
						opts.parity_str = newparity_str;
					}
					fd_printf(STO, "\r\n*** parity: %s ***\r\n", 
							  opts.parity_str);
					break;
				case KEY_BITS:
					newbits = bits_next(opts.databits);
					term_set_databits(tty_fd, newbits);
					tty_q.len = 0; term_flush(tty_fd);
					if ( term_apply(tty_fd) >= 0 ) opts.databits = newbits;
					fd_printf(STO, "\r\n*** databits: %d ***\r\n", 
							  opts.databits);
					break;
				case KEY_SEND:
					fd_printf(STO, "\r\n*** file: ");
					r = fd_readline(STI, STO, fname, sizeof(fname));
					fd_printf(STO, "\r\n");
					if ( r < -1 && errno == EINTR ) break;
					if ( r <= -1 )
						fatal("cannot read filename: %s", strerror(errno));
					run_cmd(tty_fd, opts.send_cmd, fname, NULL);
					break;
				case KEY_RECEIVE:
					fd_printf(STO, "*** file: ");
					r = fd_readline(STI, STO, fname, sizeof(fname));
					fd_printf(STO, "\r\n");
					if ( r < -1 && errno == EINTR ) break;
					if ( r <= -1 )
						fatal("cannot read filename: %s", strerror(errno));
					if ( fname[0] )
						run_cmd(tty_fd, opts.send_cmd, fname, NULL);
					else
						run_cmd(tty_fd, opts.receive_cmd, NULL);
					break;
				case KEY_BREAK:
					term_break(tty_fd);
					fd_printf(STO, "\r\n*** break sent ***\r\n");
					break;
				default:
					break;
				}
				break;

			case ST_TRANSPARENT:
				if ( c == opts.escape ) {
					state = ST_COMMAND;
				} else {
					if (tty_q.len <= TTY_Q_SZ)
						tty_q.buff[tty_q.len++] = c;
					else
						fd_printf(STO, "\x07");
				}
				break;

			default:
				assert(0);
				break;
			}
		}

		if ( FD_ISSET(tty_fd, &rdset) ) {

			/* read from port */

			do {
				n = read(tty_fd, &c, 1);
			} while (n < 0 && errno == EINTR);
			if (n == 0)
				fatal("term closed");
			else if ( n < 0 )
				fatal("read from term failed: %s", strerror(errno));
			
			do {
				n = write(STO, &c, 1);
			} while ( errno == EAGAIN 
					  || errno == EWOULDBLOCK
					  || errno == EINTR );
			if ( n <= 0 )
				fatal("write to stdout failed: %s", strerror(errno));
		}

		if ( FD_ISSET(tty_fd, &wrset) ) {

			/* write to port */

			do {
				n = write(tty_fd, tty_q.buff, tty_q.len);
			} while ( n < 0 && errno == EINTR );
			if ( n <= 0 )
				fatal("write to term failed: %s", strerror(errno));
			memcpy(tty_q.buff, tty_q.buff + n, tty_q.len - n);
			tty_q.len -= n;
		}
	}
}
/***********************************************************************
 *
 * Function: cmd_aboot
 *
 * Purpose: Sets autoboot source
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Always returns TRUE
 *
 * Notes: None
 *
 **********************************************************************/
BOOL_32 cmd_aboot(void) 
{
	UNS_8 *curp;
	UNS_32 addr;
	BOOL_32 processed = TRUE, ready = FALSE;
	INT_32 nexidx;
	ABOOT_SETUP_T abs;

	abs.fname [0] = '\0';
	if (parse_get_entry_count() >= 3) 
	{
		/* Get source */
		curp = get_parsed_entry(1);
		nexidx = 2;
		if (str_cmp(curp, "term") == 0) 
		{
			/* Clear break */
			term_break();
			abs.abootsrc = SRC_TERM;
		}
		else if (str_cmp(curp, "blk") == 0) 
		{
			abs.abootsrc = SRC_BLKDEV;

			/* Get filename */
			curp = get_parsed_entry(2);
			memcpy(abs.fname, curp, str_size(curp));
			abs.fname[str_size(curp)] = '\0';
			nexidx = 3;
		}
		else if (str_cmp(curp, "flash") == 0) 
		{
			abs.abootsrc = SRC_NAND;
		}
		else if (str_cmp(curp, "none") == 0) 
		{
			abs.abootsrc = SRC_NONE;
		}
		else
		{
			term_dat_out_crlf(invalsrc_msg);
			processed = FALSE;
		}

		/* Get file type */
		curp = get_parsed_entry(nexidx);
		abs.flt = FLT_NONE;
		if (str_cmp(curp, "elf") == 0) 
		{
			abs.flt = FLT_ELF;
		}
		else if (str_cmp(curp, "raw") == 0) 
		{
			abs.flt = FLT_RAW;
		}
		else if (str_cmp(curp, "bin") == 0) 
		{
			abs.flt = FLT_BIN;
		}
		else if (str_cmp(curp, "srec") == 0) 
		{
			abs.flt = FLT_SREC;
		}
		else 
		{
			abs.flt = FLT_NONE;
			term_dat_out(unkft_msg);
			term_dat_out_crlf(curp);
			processed = FALSE;
		}

		/* Next index */
		nexidx++;

		/* Handle each file type */
		if (processed == TRUE) 
		{
			switch (abs.flt) 
			{
				case FLT_RAW:
					/* Get load address */
					curp = get_parsed_entry(nexidx);
					ready = str_hex_to_val(curp, &addr);
					if (ready == TRUE) 
					{
						abs.loadaddr = addr;
						abs.startaddr = addr;
					}
					else 
					{
						term_dat_out_crlf(rawna_msg);
					}

					/* Start address */
					nexidx++;
					curp = get_parsed_entry(nexidx);
					if (curp != NULL) 
					{
						ready &= str_hex_to_val(curp, &addr);
						if (ready == TRUE) 
						{
							abs.startaddr = addr;
						}
					}
					break;

				case FLT_BIN:
					ready = FALSE; /* TBD not supported yet */
					processed = TRUE;
					break;

				case FLT_SREC:
					ready = TRUE;
					processed = TRUE;
					break;

				case FLT_ELF:
					ready = FALSE; /* TBD not supported yet */
					processed = TRUE;
					break;

				default:
					break;
			}
		}
	}

	if (ready == TRUE) 
	{
		syscfg.aboot = abs;
		cfg_save(&syscfg);
		term_dat_out_crlf(bsgood_msg);
	}
	else 
	{
		term_dat_out_crlf(bsbad_msg);
	}

	return TRUE;
}
/***********************************************************************
 *
 * Function: cmd_load
 *
 * Purpose: Load command
 *
 * Processing:
 *     For the load command, start parsing subcommand elements and
 *     route to the specific handler.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Always returns TRUE
 *
 * Notes: None
 *
 **********************************************************************/
BOOL_32 cmd_load(void) {
	UNS_8 *curp;
	UNS_32 addr;
	BOOL_32 processed = TRUE, loaded = FALSE;
	FILE_DATA_T fdata;
	SRC_LOAD_T src = SRC_TERM;
	INT_32 nexidx;
	UNS_8 *fname;

	if (parse_get_entry_count() >= 3) 
	{
		/* Get source */
		curp = get_parsed_entry(1);
		nexidx = 2;
		if (str_cmp(curp, "term") == 0) 
		{
			/* Clear break */
			term_break();
			src = SRC_TERM;
		}
		else if (str_cmp(curp, "blk") == 0) 
		{
			src = SRC_BLKDEV;
			nexidx = 3;
		}
		else if (str_cmp(curp, "flash") == 0) 
		{
			src = SRC_NAND;
		}
		else 
		{
			term_dat_out_crlf(invalsrc_msg);
			processed = FALSE;
		}

		/* Get file type */
		curp = get_parsed_entry(nexidx);
		fdata.flt = FLT_NONE;
		if (str_cmp(curp, "elf") == 0) 
		{
			fdata.flt = FLT_ELF;
		}
		else if (str_cmp(curp, "raw") == 0) 
		{
			fdata.flt = FLT_RAW;
		}
		else if (str_cmp(curp, "bin") == 0) 
		{
			fdata.flt = FLT_BIN;
		}
		else if (str_cmp(curp, "srec") == 0) 
		{
			fdata.flt = FLT_SREC;
		}
		else 
		{
			fdata.flt = FLT_NONE;
			term_dat_out(unkft_msg);
			term_dat_out_crlf(curp);
			processed = FALSE;
		}

		/* Next index */
		nexidx++;

		/* Handle each file type */
		if (processed == TRUE) 
		{
			/* Get filename */
			fname = get_parsed_entry(2);

			switch (fdata.flt) 
			{
				case FLT_RAW:
					/* Get load address */
					curp = get_parsed_entry(nexidx);
					loaded = str_hex_to_val(curp, &addr);
					if (loaded == TRUE) 
					{
						fdata.loadaddr = addr;
						fdata.startaddr = (PFV) addr;
					}
					else 
					{
						term_dat_out_crlf(rawna_msg);
					}

					/* Start address */
					nexidx++;
					curp = get_parsed_entry(nexidx);
					if (curp != NULL) 
					{
						loaded &= str_hex_to_val(curp, &addr);
						if (loaded == TRUE) 
						{
							fdata.startaddr = (PFV) addr;
						}
					}

					if (loaded == TRUE) 
					{
						loaded = raw_load(&fdata, fdata.loadaddr,
							fname, src);
					}

					processed = TRUE;
					break;

				case FLT_BIN:
					processed = TRUE; /* TBD not supported yet */
					break;

				case FLT_SREC:
					loaded = srec_parse(&fdata, src, fname);
					break;

				case FLT_ELF:
					processed = TRUE; /* TBD not supported yet */
					break;

				default:
					break;
			}
		}
	}

	if (loaded == TRUE) 
	{
		term_dat_out_crlf(floaded_msg);
		sysinfo.lfile.loadaddr = fdata.loadaddr;
		sysinfo.lfile.flt = fdata.flt;
		sysinfo.lfile.num_bytes = fdata.num_bytes;
		sysinfo.lfile.startaddr = fdata.startaddr;
		sysinfo.lfile.contiguous = fdata.contiguous;
		sysinfo.lfile.loaded = TRUE;
	}
	else 
	{
		term_dat_out_crlf(notloaded_msg);
		sysinfo.lfile.loadaddr = 0xFFFFFFFF;
		sysinfo.lfile.flt = FLT_NONE;
		sysinfo.lfile.num_bytes = 0;
		sysinfo.lfile.startaddr = (PFV) 0xFFFFFFFF;
		processed = FALSE;
	}

	return TRUE;
}
Exemplo n.º 4
0
/***********************************************************************
 *
 * Function: raw_load
 *
 * Purpose: Load a raw file from a source to memory
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     fdata : Pointer to file data to fill
 *     addr  : Address to load data
 *     filename : Filename (sd cards only)
 *     src   : Data source
 *
 * Outputs: None
 *
 * Returns: TRUE if the file was loaded, otherwise FALSE
 *
 * Notes: None
 *
 **********************************************************************/
BOOL_32 raw_load(FILE_DATA_T *fdata,
                 UNS_32 addr,
                 UNS_8 *filename,
                 SRC_LOAD_T src) 
{
	UNS_32 rb, bytes = 0;
	UNS_8 ch, *ptr8 = (UNS_8 *) addr;
	BOOL_32 readloop, loaded = FALSE;

	if (src == SRC_TERM) 
	{
		term_dat_out_crlf(rawdl_msg);

		/* Read data from terminal until a break is encountered */
		while (term_break() == FALSE) 
		{
			if (term_dat_in(&ch, 1) > 0) 
			{
				bytes++;
				*ptr8 = ch;
				ptr8++;
			}
		}

		fdata->num_bytes = bytes;
		fdata->contiguous = TRUE;
		loaded = TRUE;
	}
	else if (src == SRC_NAND) 
	{
		/* Move image in NAND to memory */
		term_dat_out_crlf(rawnanddlns_msg);

	}
	else if (src == SRC_BLKDEV) 
	{
		/* Initialize FAT interface first */
		if (fat_init() == FALSE)
		{
			term_dat_out(blkdeverr_msg);
		}
		/* Try to open file */
		else if (fat_file_open(filename) == FALSE) 
		{
			term_dat_out_crlf(nofilmsg);
		}
		else 
		{
			fdata->num_bytes = 0;
			readloop = TRUE;
			while (readloop == TRUE) 
			{
				rb = fat_file_read(ptr8, 8);
				fdata->num_bytes += rb;
				ptr8 += 8;
				if (rb != 8) 
				{
					readloop = FALSE;
				}
			}
			fdata->contiguous = TRUE;
			loaded = TRUE;
		}

		fat_deinit();
	}

	return loaded;
}
Exemplo n.º 5
0
/***********************************************************************
 *
 * Function: readline
 *
 * Purpose: Read line with line feed
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     data : Pointer to line data to fill
 *     src  : Data source
 *
 * Outputs: None
 *
 * Returns: TRUE if the line was loaded, otherwise FALSE
 *
 * Notes: None
 *
 **********************************************************************/
static BOOL_32 readline(UNS_8 *data,
                        SRC_LOAD_T src) 
{
	UNS_32 rb;
	int lastidx, idx;
	BOOL_32 linedone = FALSE, linegood = FALSE;

	lastidx = idx = 0;
	while (linedone == FALSE) 
	{
		switch (src) 
		{
			case SRC_TERM:
				/* Has a break occurred? */
				if (term_break() == TRUE) 
				{
					/* Exit now */
					linedone = TRUE;
				}
				else if (term_dat_in((data + idx), 1) > 0) 
				{
					idx++;
				}
				break;

			case SRC_NAND:
				/* Get a byte from the FLASH */
				/* Get a byte from the SD/MMC card */
				rb = stream_flash_read(&data [idx], 1);
				if (rb == 0) 
				{
					linedone = TRUE;
				}
				idx++;
				break;

			case SRC_BLKDEV:
				/* Get a byte from the SD/MMC card */
				rb = fat_file_read(&data [idx], 1);
				if (rb == 0) 
				{
					linedone = TRUE;
				}
				idx++;
				break;

			case SRC_NONE:
			default:
				return FALSE;
		}

		if (lastidx != idx) 
		{
			if (data [lastidx] == '\r') 
			{
				linedone = TRUE;
				linegood = TRUE;
				data [lastidx] = '\0';
			}

			lastidx = idx;
		}
	}

	data [idx] = '\0';
	str_upper_to_lower(data);
	return linegood;
}
Exemplo n.º 6
0
/* Process command key. Returns non-zero if command results in picocom
   exit, zero otherwise. */
int
do_command (unsigned char c)
{
	static int dtr_up = 0;
	int newbaud, newflow, newparity, newbits, newstopbits;
	const char *xfr_cmd;
	char *fname;
	int r;

	switch (c) {
	case KEY_EXIT:
		return 1;
	case KEY_QUIT:
		term_set_hupcl(tty_fd, 0);
		term_flush(tty_fd);
		term_apply(tty_fd, 1);
		term_erase(tty_fd);
		return 1;
	case KEY_STATUS:
		show_status(dtr_up);
		break;
	case KEY_HELP:
	case KEY_KEYS:
		show_keys();
		break;
	case KEY_PULSE:
		fd_printf(STO, "\r\n*** pulse DTR ***\r\n");
		if ( term_pulse_dtr(tty_fd) < 0 )
			fd_printf(STO, "*** FAILED\r\n");
		break;
	case KEY_TOGGLE:
		if ( dtr_up )
			r = term_lower_dtr(tty_fd);
		else
			r = term_raise_dtr(tty_fd);
		if ( r >= 0 ) dtr_up = ! dtr_up;
		fd_printf(STO, "\r\n*** DTR: %s ***\r\n", 
				  dtr_up ? "up" : "down");
		break;
	case KEY_BAUD:
	case KEY_BAUD_UP:
	case KEY_BAUD_DN:
		if ( c== KEY_BAUD) {
			newbaud = read_baud();
			if ( newbaud < 0 ) {
				fd_printf(STO, "*** cannot read baudrate ***\r\n");
				break;
			}
			opts.baud = newbaud;
		} else if (c == KEY_BAUD_UP) {
			opts.baud = baud_up(opts.baud);
		} else {
			opts.baud = baud_down(opts.baud);
		}
		term_set_baudrate(tty_fd, opts.baud);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbaud = term_get_baudrate(tty_fd, NULL);
		if ( opts.baud != newbaud ) {
			fd_printf(STO, "\r\n*** baud: %d (%d) ***\r\n", 
					  opts.baud, newbaud);
		} else {
			fd_printf(STO, "\r\n*** baud: %d ***\r\n", opts.baud);
		}
		set_tty_write_sz(newbaud);
		break;
	case KEY_FLOW:
		opts.flow = flow_next(opts.flow);
		term_set_flowcntrl(tty_fd, opts.flow);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newflow = term_get_flowcntrl(tty_fd);
		if ( opts.flow != newflow ) {
			fd_printf(STO, "\r\n*** flow: %s (%s) ***\r\n", 
					  flow_str[opts.flow], flow_str[newflow]);
		} else {
			fd_printf(STO, "\r\n*** flow: %s ***\r\n", 
					  flow_str[opts.flow]);
		}
		break;
	case KEY_PARITY:
		opts.parity = parity_next(opts.parity);
		term_set_parity(tty_fd, opts.parity);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newparity = term_get_parity(tty_fd);
		if (opts.parity != newparity ) {
			fd_printf(STO, "\r\n*** parity: %s (%s) ***\r\n",
					  parity_str[opts.parity], 
					  parity_str[newparity]);
		} else {
			fd_printf(STO, "\r\n*** parity: %s ***\r\n", 
					  parity_str[opts.parity]);
		}
		break;
	case KEY_BITS:
		opts.databits = bits_next(opts.databits);
		term_set_databits(tty_fd, opts.databits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newbits = term_get_databits(tty_fd);
		if (opts.databits != newbits ) {
			fd_printf(STO, "\r\n*** databits: %d (%d) ***\r\n",
					  opts.databits, newbits);
		} else {
			fd_printf(STO, "\r\n*** databits: %d ***\r\n", 
					  opts.databits);
		}
		break;
	case KEY_STOP:
		opts.stopbits = stopbits_next(opts.stopbits);
		term_set_stopbits(tty_fd, opts.stopbits);
		tty_q.len = 0; term_flush(tty_fd);
		term_apply(tty_fd, 1);
		newstopbits = term_get_stopbits(tty_fd);
		if (opts.stopbits != newstopbits ) {
			fd_printf(STO, "\r\n*** stopbits: %d (%d) ***\r\n",
					  opts.stopbits, newstopbits);
		} else {
			fd_printf(STO, "\r\n*** stopbits: %d ***\r\n", 
					  opts.stopbits);
		}
		break;
	case KEY_LECHO:
		opts.lecho = ! opts.lecho;
		fd_printf(STO, "\r\n*** local echo: %s ***\r\n", 
				  opts.lecho ? "yes" : "no");
		break;
	case KEY_SEND:
	case KEY_RECEIVE:
		xfr_cmd = (c == KEY_SEND) ? opts.send_cmd : opts.receive_cmd;
		if ( xfr_cmd[0] == '\0' ) {
			fd_printf(STO, "\r\n*** command disabled ***\r\n");
			break;
		}
		fname = read_filename();
		if (fname == NULL) {
			fd_printf(STO, "*** cannot read filename ***\r\n");
			break;
		}
		run_cmd(tty_fd, xfr_cmd, fname);
		free(fname);
		break;
	case KEY_BREAK:
		term_break(tty_fd);
		fd_printf(STO, "\r\n*** break sent ***\r\n");
		break;
	default:
		break;
	}

	return 0;
}