# HG changeset patch # User Michael Spacefalcon # Date 1367639260 0 # Node ID 67a39d8914a83882c3cb528b73cb9ca8cb6b532b # Parent be293e656a6f5013c894a99cb9099e6714b111f9 starting work on loadtool diff -r be293e656a6f -r 67a39d8914a8 loadtools/Makefile --- a/loadtools/Makefile Sat May 04 00:35:55 2013 +0000 +++ b/loadtools/Makefile Sat May 04 03:47:40 2013 +0000 @@ -5,7 +5,10 @@ SERTOOL_OBJS= defpath.o hexdecode.o hwparam.o romload.o sercomm.o sertool.o \ srecreader.o ttypassthru.o -all: ${PROGS} +LOADTOOL_OBJS= defpath.o hexdecode.o hwparam.o romload.o sercomm.o \ + srecreader.o tpinterf.o + +all: ${PROGS} ${LOADTOOL_OBJS} fc-sertool: ${SERTOOL_OBJS} ${CC} -o $@ ${SERTOOL_OBJS} diff -r be293e656a6f -r 67a39d8914a8 loadtools/hwparam.c --- a/loadtools/hwparam.c Sat May 04 00:35:55 2013 +0000 +++ b/loadtools/hwparam.c Sat May 04 03:47:40 2013 +0000 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff -r be293e656a6f -r 67a39d8914a8 loadtools/tpinterf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/tpinterf.c Sat May 04 03:47:40 2013 +0000 @@ -0,0 +1,166 @@ +/* + * Target program interface - this module provides some primitives + * for communicating programmatically with loadagent and possibly + * other target-utils. + */ + +#include +#include +#include +#include +#include +#include + +extern int errno; + +extern int target_fd; + +/* definition matches ../target-utils/libcommon/cmdentry.c */ +#define MAXCMD 527 + +/* + * static buffer between tpinterf_make_cmd and tpinterf_send_cmd + * + * We store the command with an ending \r\n so we can use it for + * matching the received echo as well, hence the sizing of the + * buffer. + */ +static char cmdbuf[MAXCMD+2]; +static int cmdlen; + +static int +arg_chars_valid(arg) + char *arg; +{ + char *cp; + + for (cp = arg; *cp; cp++) + if (*cp < ' ' || *cp > '~') + return(0); + return(1); +} + +/* + * This function takes a command for the target in argv form and + * converts it to a space-separated continuous string which can be + * passed as tty "keyboard" input to the target, enforcing length + * and character validity limits in the process. The output is + * stored in an internal static buffer for subsequent + * tpinterf_send_cmd(). + * + * Return value: 0 if everything OK, or -1 if some constraint is + * violated. + */ +tpinterf_make_cmd(argv) + char **argv; +{ + int arglen; + char **ap, *dp; + + dp = cmdbuf; + cmdlen = 0; + for (ap = argv; *ap; ap++) { + arglen = strlen(*ap); + if (ap != argv) + arglen++; /* separating space */ + if (arglen > MAXCMD - cmdlen) + return(-1); + if (!arg_chars_valid(*ap)) + return(-1); + if (ap != argv) + *dp++ = ' '; + strcpy(dp, *ap); + dp += strlen(*ap); + cmdlen += arglen; + } + *dp++ = '\r'; + *dp = '\n'; + return(0); +} + +/* + * This function sends the previously-constructed command to the target, + * and collects the expected response. + * + * Return value: 0 if successful, -1 on errors (timeout or wrong response) + */ +tpinterf_send_cmd() +{ + char echobuf[MAXCMD+2]; + fd_set fds; + struct timeval tv; + int rcvd, cc; + + write(target_fd, cmdbuf, cmdlen + 1); + for (rcvd = 0; rcvd < cmdlen + 2; ) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = 1; + tv.tv_usec = 0; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + if (cc < 1) + return(-1); + cc = read(target_fd, echobuf + rcvd, cmdlen + 2 - rcvd); + if (cc <= 0) { + perror("read after successful select"); + exit(1); + } + rcvd += cc; + } + if (bcmp(echobuf, cmdbuf, cmdlen + 2)) + return(-1); + else + return(0); +} + +/* + * This functions reads the serial output from the target until a + * '=' prompt is received. All intermediate output is passed to + * stdout. + * + * Return value: 0 if '=' prompt received, -1 otherwise (timeout) + */ +tpinterf_pass_output() +{ + char buf[512], *cp; + fd_set fds; + struct timeval tv; + int cc, newline = 1; + + for (;;) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = 1; + tv.tv_usec = 0; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + exit(1); + } + if (cc < 1) + return(-1); + cc = read(target_fd, buf, sizeof buf); + if (cc <= 0) { + perror("read after successful select"); + exit(1); + } + for (cp = buf; cc; cp++) { + cc--; + if (*cp == '=' && newline && !cc) + return(0); + putchar(*cp); + if (*cp == '\n') + newline = 1; + else + newline = 0; + } + } +}