changeset 21:67a39d8914a8

starting work on loadtool
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sat, 04 May 2013 03:47:40 +0000
parents be293e656a6f
children e658a84b37df
files loadtools/Makefile loadtools/hwparam.c loadtools/tpinterf.c
diffstat 3 files changed, 171 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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}
--- 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 <sys/param.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <string.h>
 #include <strings.h>
 #include <stdlib.h>
 
--- /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 <sys/types.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+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;
+		}
+	}
+}