FreeCalypso > hg > freecalypso-sw
diff loadtools/tpinterf2.c @ 35:05af070c4b60
loadtool: preparations for dump2bin and dump2srec
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 05 May 2013 02:24:56 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/loadtools/tpinterf2.c Sun May 05 02:24:56 2013 +0000 @@ -0,0 +1,113 @@ +/* + * This module provides a more advanced target interface function + * than tpinterf.c - programmatic capture of target responses, + * for dumps etc. It will be linked by fc-loadtool, but not fc-chainload. + */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> + +extern int errno; + +extern int target_fd; + +/* + * This functions reads the serial output from the target until a + * '=' prompt is received. All intermediate output is parsed into + * lines and passed to a callback function. + * + * The callback function is called with a pointer to each received + * line, stored in a buffer ending in NUL, with CRLF stripped. + * The callback function is expected to return an int. If the + * callback return value is negative, this function returns immediately + * with that negative value. If the callback return value is positive + * or zero, it is added to an accumulator. + * + * Termination: this function returns when it has received a '=' at + * the beginning of a line (return value is the callback return + * accumulator, or 0 if no lines came), if the callback returns a + * negative value (that value is returned), or if an error is detected + * within this function (return value -1, and an error message + * printed on stderr). + */ +tpinterf_capture_output(timeout, callback) + int timeout; /* seconds */ + int (*callback)(); +{ + char buf[512], *cp; + char line[1024], *dp = line; + fd_set fds; + struct timeval tv; + int cc, linelen = 0; + int totout = 0, cbret; + + for (;;) { + FD_ZERO(&fds); + FD_SET(target_fd, &fds); + tv.tv_sec = timeout; + tv.tv_usec = 0; + cc = select(target_fd+1, &fds, NULL, NULL, &tv); + if (cc < 0) { + if (errno == EINTR) + continue; + perror("select"); + return(-1); + } + if (cc < 1) { + fprintf(stderr, + "error: timeout waiting for \'=\' prompt from target\n"); + return(-1); + } + cc = read(target_fd, buf, sizeof buf); + if (cc <= 0) { + perror("read after successful select"); + return(-1); + } + for (cp = buf; cc; cp++) { + cc--; + if (*cp == '=' && !linelen && !cc) + return(totout); + if (*cp == '\r') + continue; + if (*cp == '\n') { + *dp = '\0'; + cbret = callback(line); + if (cbret < 0) + return(cbret); + totout += cbret; + dp = line; + linelen = 0; + continue; + } + *dp++ = *cp; + linelen++; + if (linelen >= sizeof line) { + fprintf(stderr, + "error: target response line length exceeds buffer\n"); + return(-1); + } + } + } +} + +/* single line response capture mechanism */ +/* same line buffer size as in tpinterf_capture_output() */ +char target_response_line[1024]; + +static +oneline_catcher(linein) + char *linein; +{ + strcpy(target_response_line, linein); + return(1); +} + +tpinterf_capture_output_oneline(timeout) +{ + return tpinterf_capture_output(timeout, oneline_catcher); +}