void command_mode(void) { char buf[256], *p; terminal_mode(TERMINAL_COOKED); printf("\n" "pconsole command mode\n" ">>> "); fflush(stdout); flags |= FLAGS_CMD_MODE; while((p = fgets(buf, 256, stdin)) != NULL) { cstrip_line(buf); if (*buf) pcommand(buf); if (flags & FLAGS_CMD_MODE) { if (*buf) printf("\n"); printf(">>> "); fflush(stdout); } else break; } if (p == NULL) { if (AllConns == NULL) { printf("\n\n"); terminal_mode(TERMINAL_COOKED); exit(0); } else printf("<Ctrl-D>\n"); } flags &= ~FLAGS_CMD_MODE; printf("\n" "Press <Ctlr-A> for command mode\n" "> "); fflush(stdout); terminal_mode(TERMINAL_RAW); }
void pconsole(void) { int key, typed = 0; char kar; Conn *c, *c_next; if (AllConns == NULL) command_mode(); /* start in command mode */ else { printf("\n" "Press <Ctlr-A> for command mode\n" "> "); fflush(stdout); terminal_mode(TERMINAL_RAW); } while(read(fileno(stdin), &kar, 1) > 0) { key = kar & 0xff; if (key == 1) { /* Ctrl-A => command mode */ printf("<Ctrl-A>\n"); command_mode(); continue; } if (key == KEY_CTRL('S')) { /* Ctrl-S => toggle echo */ printf("<Ctrl-S> "); cmd_echo(NULL); printf("> "); fflush(stdout); typed = 0; continue; } if (key == '\r' || key == '\n') { /* return */ printf("\n> "); fflush(stdout); typed = 0; } else { if (flags & FLAGS_ECHO) { if (key == 0x7f || key == '\b') { /* backspace */ if (typed) { printf("\b \b"); fflush(stdout); typed--; } } else { if (key >= ' ' && key <= '~') { fputc(key, stdout); typed++; } else { switch(key) { case 0x1b: printf("<Esc>"); break; case '\t': printf("<Tab>"); break; default: printf("<Ctrl-%c>", key - 1 + 'A'); } printf("\n> "); typed = 0; } fflush(stdout); } } } /* put character in everyones input buffer */ for(c = AllConns; c != NULL; c = c_next) { c_next = c->next; if (c->fd > 0) { seteuid(0); /* regain root privs */ if (ioctl(c->fd, TIOCSTI, &kar) == -1) { /* simulate terminal input */ seteuid(getuid()); /* drop root privs again */ printf("\nioctl() : %s\n", strerror(errno)); if (c->hostname != NULL) printf("detaching from %s#%s\n", c->hostname, c->dev); else printf("detaching from %s\n", c->dev); remove_Conn(c); destroy_Conn(c); } else seteuid(getuid()); /* drop the root privs */ } } if (AllConns == NULL) command_mode(); } }
int main(int argc, char *argv[]) { char actualport[PATH_MAX]; char *infile = NULL, *p, *p2; int terminalMode = FALSE; BoardConfig *config, *configSettings; char *port, *board, *subtype, *value; System sys; int baud = 115200; int portFlags = 0; int flags = 0; int i; int terminalBaud = 0; int check_for_exit = 0; /* flag to terminal_mode to check for a certain sequence to indicate program exit */ int showPorts = FALSE; int showAll = TRUE; int pstMode = FALSE; /* make sure that the serial port gets closed on exit */ atexit(serial_done); /* just display a usage message if no arguments are supplied */ if (argc <= 1) Usage(); /* get the environment settings */ port = getenv("PROPELLER_LOAD_PORT"); board = getenv("PROPELLER_LOAD_BOARD"); /* setup a configuration to collect command line -D settings */ configSettings = NewBoardConfig(NULL, ""); /* get the arguments */ for(i = 1; i < argc; ++i) { /* handle switches */ if(argv[i][0] == '-') { switch(argv[i][1]) { case 'b': // select a target board if (argv[i][2]) board = &argv[i][2]; else if (++i < argc) board = argv[i]; else Usage(); break; case 'p': if(argv[i][2]) port = &argv[i][2]; else if(++i < argc) port = argv[i]; else Usage(); #if defined(CYGWIN) || defined(WIN32) || defined(LINUX) if (isdigit((int)port[0])) { #if defined(CYGWIN) || defined(WIN32) static char buf[10]; sprintf(buf, "COM%d", atoi(port)); port = buf; #endif #if defined(LINUX) static char buf[64]; sprintf(buf, "/dev/ttyUSB%d", atoi(port)); port = buf; #endif } #endif #if defined(MACOSX) if (port[0] != '/') { static char buf[64]; sprintf(buf, "/dev/cu.usbserial-%s", port); port = buf; } #endif break; case 'P': showPorts = TRUE; showAll = FALSE; break; case 'Q': showPorts = TRUE; showAll = TRUE; break; case 'e': flags |= LFLAG_WRITE_EEPROM; break; case 'l': flags |= LFLAG_WRITE_SDLOADER; break; case 'z': flags |= LFLAG_WRITE_SDCACHELOADER; break; case 'r': flags |= LFLAG_RUN; break; case 's': flags |= LFLAG_WRITE_BINARY; break; case 'x': flags |= LFLAG_WRITE_PEX; break; case 'T': pstMode = TRUE; // fall through case 't': terminalMode = TRUE; if (argv[i][2]) terminalBaud = atoi(&argv[i][2]); break; case 'q': check_for_exit = 1; break; case 'g': flags |= LFLAG_DEBUG; break; case 'D': if(argv[i][2]) p = &argv[i][2]; else if(++i < argc) p = argv[i]; else Usage(); if ((p2 = strchr(p, '=')) == NULL) Usage(); *p2++ = '\0'; SetConfigField(configSettings, p, p2); break; case 'I': if(argv[i][2]) p = &argv[i][2]; else if(++i < argc) p = argv[i]; else Usage(); xbAddPath(p); break; case 'v': portFlags = IFLAG_VERBOSE; break; case 'S': psetdelay(argv[i][2] ? atoi(&argv[i][2]) : 5); break; case 'f': flags |= LFLAG_WRITE_SDFILE; break; case '?': /* fall through */ default: Usage(); break; } } /* handle the input filename */ else { if (infile) Usage(); infile = argv[i]; } } /* make sure an input file was specified if needed */ if (infile && !flags) { printf("error: must specify -e, -r, or -s when an image file is specified\n"); return 1; } /* 1) look in the directory specified by the -I command line option (added above) 2) look in the directory where the elf file resides 3) look in the directory pointed to by the environment variable PROPELLER_ELF_LOAD 4) look in the directory where the loader executable resides if possible 5) look in /usr/local/propeller/propeller-load */ /* finish the include path */ if (infile) xbAddFilePath(infile); xbAddEnvironmentPath("PROPELLER_LOAD_PATH"); xbAddProgramPath(argv); #if defined(LINUX) || defined(MACOSX) || defined(CYGWIN) xbAddPath("/opt/parallax/propeller-load"); #endif sys.ops = &myOps; /* parse the board option */ if (board) { /* split the board type from the subtype */ if ((p = strchr(board, ':')) != NULL) { *p++ = '\0'; subtype = p; } /* no subtype */ else subtype = DEF_SUBTYPE; } else { board = DEF_BOARD; subtype = DEF_SUBTYPE; } /* setup for the selected board */ if (!(config = ParseConfigurationFile(&sys, board))) { printf("error: can't find board configuration '%s'\n", board); return 1; } /* select the subtype */ if (subtype) { if (!(config = GetConfigSubtype(config, subtype))) { printf("error: can't find board configuration subtype '%s'\n", subtype); return 1; } } /* override with any command line settings */ config = MergeConfigs(config, configSettings); /* use the baud rate from the configuration */ GetNumericConfigField(config, "baudrate", &baud); /* Use reset method from configuration */ if ((value = GetConfigField(config, "reset")) != NULL) { if (use_reset_method (value)) { printf("error: no reset type '%s'\n", value); return 1; } } else { use_reset_method ("dtr"); } /* check for being asked to show ports */ if (showPorts) { if (showAll) ShowPorts(PORT_PREFIX); else ShowConnectedPorts(PORT_PREFIX, baud, portFlags); return 0; } /* initialize the serial port */ if ((flags & NEED_PORT) != 0 || terminalMode) { int sts = InitPort(PORT_PREFIX, port, baud, portFlags, actualport); switch (sts) { case PLOAD_STATUS_OK: // port initialized successfully break; case PLOAD_STATUS_OPEN_FAILED: printf("error: opening serial port '%s'\n", port); perror("Error is "); return 1; case PLOAD_STATUS_NO_PROPELLER: if (port) printf("error: no propeller chip on port '%s'\n", port); else printf("error: can't find a port with a propeller chip\n"); return 1; } } /* load the image file */ if (infile) { if (flags & LFLAG_WRITE_SDFILE) WriteFileToSDCard(config, infile, NULL); else { if (!LoadImage(&sys, config, infile, flags)) { printf("error: load failed\n"); return 1; } } } /* check for loading the sd loader */ else if (flags & LFLAG_WRITE_SDLOADER) { if (!LoadSDLoader(&sys, config, "sd_loader.elf", flags)) { printf("error: load failed\n"); return 1; } } /* check for loading the sd cache loader */ else if (flags & LFLAG_WRITE_SDCACHELOADER) { if (!LoadSDCacheLoader(&sys, config, "sd_cache_loader.elf", flags)) { printf("error: load failed\n"); return 1; } } /* enter terminal mode if requested */ if (terminalMode) { printf("[ Entering terminal mode. Type ESC or Control-C to exit. ]\n"); fflush(stdout); if (terminalBaud && terminalBaud != baud) { serial_done(); serial_init(actualport, terminalBaud); } terminal_mode(check_for_exit, pstMode); } return 0; }