/* exception(): * This is the first 'C' function called out of a monitor-installed * exception handler. */ void exception(void) { /* ADD_CODE_HERE */ /* Populating these two values is target specific. * Refer to other target-specific examples for details. * In some cases, these values are extracted from registers * already put into the register cache by the lower-level * portion of the exception handler in vectors_template.s */ ExceptionAddr = 0; ExceptionType = 0; /* Allow the console uart fifo to empty... */ flushconsole(); monrestart(EXCEPTION); }
void flush_log (void) { if (debugfile) fflush (debugfile); flushconsole (); }
void console_flush (void) { flushconsole (); }
int main(int argc, char **argv, char **envp) { struct termios tty; char filename[MAX_FILEPATH]; char ch; int speed; int opt; int oflags; int ret; while ((opt = getopt(argc, argv, ":dt:b:hl:")) != -1) { switch(opt) { case 'd': debug++; break; case 't': g_ttydev = optarg; break; case 'b': g_baud = atoi(optarg); break; case 'h': show_usage(argv[0], 0); break; case 'l': g_logfile = optarg; break; case ':': fprintf(stderr, "ERROR: Missing argument to option '%c'\n", optopt); show_usage(argv[0], 1); break; case '?': fprintf(stderr, "ERROR: Unrecognized option '%c'\n", optopt); show_usage(argv[0], 2); break; } } if (optind < argc) { fprintf(stderr, "ERROR: Unexpected arguments at end of line\n"); show_usage(argv[0], 3); } switch (g_baud) { case 0: speed = B0; break; case 50: speed = B50; break; case 75: speed = B75; break; case 110: speed = B110; break; case 134: speed = B134; break; case 150: speed = B150; break; case 200: speed = B200; break; case 300: speed = B300; break; case 600: speed = B600; break; case 1200: speed = B1200; break; case 1800: speed = B1800; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; case 38400: speed = B38400; break; case 57600: speed = B57600; break; case 115200: speed = B115200; break; case 230400: speed = B230400; break; default: fprintf(stderr, "ERROR: Unsupported BAUD=%d\n", g_baud); show_usage(argv[0], 4); } /* Was a log file specified? */ if (g_logfile) { g_logstream = fopen(g_logfile, "w"); if (!g_logstream) { fprintf(stderr, "ERROR: Failed to open '%s' for writing\n", g_logfile); return 5; } } /* Set the host stdin to O_NONBLOCK */ oflags = fcntl(0, F_GETFL, 0); if (oflags == -1) { fprintf(stderr, "ERROR: fnctl(F_GETFL) failed: %s\n", strerror(errno)); return 6; } ret = fcntl(0, F_SETFL, oflags | O_NONBLOCK); if (ret < 0) { fprintf(stderr, "ERROR: fnctl(F_SETFL) failed: %s\n", strerror(errno)); return 7; } /* Open the selected serial port (blocking)*/ g_fd = open(g_ttydev, O_RDWR); if (g_fd < 0) { printconsole("ERROR: Failed to open %s: %s\n", g_ttydev, strerror(errno)); return 8; } /* Configure the serial port in at the selected baud in 8-bit, no-parity, raw mode * and turn off echo, etc. */ ret = tcgetattr(g_fd, &g_termios); if (ret < 0) { printconsole("ERROR: Failed to get termios for %s: %s\n", g_ttydev, strerror(errno)); close(g_fd); return 9; } memcpy(&tty, &g_termios, sizeof(struct termios)); tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); tty.c_oflag &= ~OPOST; tty.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); tty.c_cflag &= ~(CSIZE|PARENB); tty.c_cflag |= CS8; (void)cfsetispeed(&tty, speed); (void)cfsetospeed(&tty, speed); ret = tcsetattr(g_fd, TCSANOW, &tty); if (ret < 0) { printconsole("ERROR: Failed to set termios for %s: %s\n", g_ttydev, strerror(errno)); close(g_fd); return 10; } #if 1 /* Open the selected serial port (non-blocking)*/ g_fdnb = open(g_ttydev, O_RDONLY | O_NONBLOCK); if (g_fdnb < 0) { printconsole("ERROR: Failed to open %s: %s\n", g_ttydev, strerror(errno)); return 11; } #else /* Create a non-blocking copy of the configure tty descriptor */ g_fdnb = dup(g_fd); if (g_fdnb < 0) { printconsole("ERROR: Failed to dup %s fd=%d: %s\n", g_ttydev, g_fd, strerror(errno)); close_tty(); return 12; } oflags = fcntl(g_fdnb, F_GETFL, 0); if (oflags == -1) { fprintf(stderr, "ERROR: fnctl(F_GETFL) failed: %s\n", strerror(errno)); close_tty(); return 13; } ret = fcntl(g_fdnb, F_SETFL, oflags | O_NONBLOCK); if (ret < 0) { fprintf(stderr, "ERROR: fnctl(F_SETFL) failed: %s\n", strerror(errno)); close_tty(); return 14; } #endif /* Catch attempts to control-C out of the program so that we can restore * the TTY settings. */ signal(SIGINT, interrupt); /* Loopo until control-C */ for (;;) { /* Read characters from the console, and echo them to the target tty */ ret = readbyte(0, &ch); if (ret == 0) { printconsole("End-of-file: exitting\n"); close_tty(); return 0; } else if (ret == 1) { writebyte(g_fd, ch); } /* Read characters from target TTY and echo them on the console */ ret = readbyte(g_fdnb, &ch); if (ret == 0) { printconsole("ERROR: Unexpected number of bytes read(%d) from %s\n", ret, g_ttydev); close_tty(); return 15; } else if (ret == 1) { if (ch == ENQ) { char ch1; char ch2; writebyte(g_fd, '*'); ret = readbyte(g_fd, &ch1); if (ret != 1) { printconsole("ERROR: Unexpected number of bytes read(%d) from %s\n", ret, g_ttydev); close_tty(); return 15; } ret = readbyte(g_fd, &ch2); if (ret != 1) { printconsole("ERROR: Unexpected number of bytes read(%d) from %s\n", ret, g_ttydev); close_tty(); return 16; } getfilename(g_fd, filename); if (ch1 == 'l' || ch1 == 'L') { sendfile(g_fd, filename, 0); } else if (ch1 == 'v' || ch1 == 'V') { sendfile(g_fd, filename, 1); } else if (ch1 == 's' || ch1 == 'S') { receivefile(g_fd, filename); } } else { putconsole(ch); flushconsole(); } } } return 0; }
static void receivefile(int fdtarg, char *filename) { char ch; int fdout; int nbytes; int ndots; int ret; fdout = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fdout < 0) { fprintf(stderr, "ERROR: Failed to open '%s' for writing\n", filename); (void)writebyte(fdtarg, '>'); return; } printconsole("Receiving file '%s':\n", filename); flushconsole(); (void)writebyte(fdtarg, '+'); /* Synchronize */ do { ret = readbyte(fdtarg, &ch); } while (ret == 1 && ch != 'S' && ch != 'Q'); nbytes = 0; ndots = 0; /* Receive the file */ while (ret == 1) { /* Check for end-of-file */ if (ch == '>') { close(fdout); return; } writebyte(fdout, ch); if (++nbytes > 256) { nbytes = 0; putconsole('.'); if (++ndots > 72) { putconsole('\n'); ndots = 0; } flushconsole(); } ret = readbyte(fdtarg, &ch); if (ch == '\r') { writebyte(fdtarg, '+'); } } close (fdout); }
static void sendfile(int fdtarg, char *filename, int verify) { char chin; char chout; int fdin; int nbytes; int ndots; int ret; /* Source the source file */ fdin = open(filename, O_RDONLY); if (fdin < 0) { fprintf(stderr, "ERROR: Failed to open '%s' for reading\n", filename); (void)writebyte(fdin, '>'); return; } if (verify) { printconsole("Verifying file '%s':\n", filename); } else { printconsole("Loading file '%s':\n", filename); } flushconsole(); /* This loop processes each byte from the source file */ nbytes = 0; ndots = 0; while ((ret = readbyte(fdin, &chout)) == 1) { /* If verbose debug is OFF, then output dots at a low rate */ if (debug < 2) { if (++nbytes > 64) { nbytes = 0; putconsole('.'); if (++ndots > 72) { putconsole('\n'); ndots = 0; } flushconsole(); } } /* If verbose debug is ON, dump everything */ else if (chout == 'S') { printconsole("\n[%c", chout); } else if (isprint(chout)) { printconsole("[%c", chout); } else { printconsole("[."); } /* Send the byte to the target */ writebyte(fdtarg, chout); /* Get the response from the target. Loop until the target responds * by either echoing the byte sent or by sending '>' */ do { ret = readbyte(fdtarg, &chin); /* If verbose debug is ON, echo the response from the target */ if (ret == 1 && debug >= 2) { if (chin != chout) { if (isprint(chin)) { putconsole(chin); } else { putconsole('.'); } } else { putconsole(']'); } } /* Check if the target is asking to terminate the transfer */ if (ret == 1 && chin == '>') { close(fdin); writebyte(fdtarg, ACK); return; } } while (ret == 1 && chin != chout); } writebyte(fdtarg, '>'); do { ret = readbyte(fdtarg, &chin); } while (ret == 1 && chin != ENQ); close(fdin); writebyte(fdtarg, ACK); }