changeset 126:811b138f1bed

rvtdump utility written, compiles
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 31 Oct 2013 19:59:16 +0000
parents 17c1e2a38418
children f4f0c8738dcb
files .hgignore rvinterf/Makefile rvinterf/openport.c rvinterf/packetrx.c rvinterf/pktmux.h rvinterf/rvtdump.c rvinterf/trdump.c
diffstat 7 files changed, 331 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Oct 31 07:15:32 2013 +0000
+++ b/.hgignore	Thu Oct 31 19:59:16 2013 +0000
@@ -15,6 +15,8 @@
 ^nuc-fw/finlink/.*\.map$
 ^nuc-fw/include/config\.
 
+^rvinterf/rvtdump$
+
 ^target-utils/.*/crt0\.S$
 
 ^toolchain/binutils-2\.21\.1/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/Makefile	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,18 @@
+CC=	gcc
+CFLAGS=	-O2
+PROGS=	rvtdump
+INSTBIN=/usr/local/bin
+
+RVTDUMP_OBJS=	openport.o packetrx.o rvtdump.o trdump.o
+
+all:	${PROGS}
+
+rvtdump:	${RVTDUMP_OBJS}
+	${CC} ${CFLAGS} -o $@ ${RVTDUMP_OBJS}
+
+install:	${PROGS}
+	mkdir -p ${INSTBIN}
+	install -c ${PROGS} ${INSTBIN}
+
+clean:
+	rm -f *.o *.out *errs ${PROGS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/openport.c	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,82 @@
+/*
+ * This module takes care of opening the serial port and setting the
+ * proper "raw" termios modes, including the baud rate.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+int target_fd;
+char *baudrate_name = "115200";
+
+static struct baudrate {
+	char	*name;
+	speed_t	termios_code;
+} baud_rate_table[] = {
+	{"19200",	B19200},
+	{"38400",	B38400},
+	{"57600",	B57600},
+	{"115200",	B115200},
+	/* non-standard high baud rates "remapped" by CP2102 usb2serial IC */
+	{"203125",	B230400},
+	{"406250",	B460800},
+	{"812500",	B921600},
+	/* table search terminator */
+	{NULL,		B0}
+};
+
+static speed_t
+get_baud_rate()
+{
+	struct baudrate *br;
+
+	for (br = baud_rate_table; br->name; br++)
+		if (!strcmp(br->name, baudrate_name))
+			break;
+	if (!br->name) {
+		fprintf(stderr, "baud rate \"%s\" unknown/unsupported\n",
+			baudrate_name);
+		exit(1);
+	}
+	return br->termios_code;
+}
+
+open_target_serial(ttydev)
+	char *ttydev;
+{
+	struct termios target_termios;
+	speed_t br_code;
+
+	br_code = get_baud_rate();
+	target_fd = open(ttydev, O_RDWR|O_NONBLOCK);
+	if (target_fd < 0) {
+		perror(ttydev);
+		exit(1);
+	}
+	target_termios.c_iflag = IGNBRK;
+	target_termios.c_oflag = 0;
+	target_termios.c_cflag = CLOCAL|HUPCL|CREAD|CS8;
+	target_termios.c_lflag = 0;
+	target_termios.c_cc[VMIN] = 1;
+	target_termios.c_cc[VTIME] = 0;
+	cfsetispeed(&target_termios, br_code);
+	cfsetospeed(&target_termios, br_code);
+	if (tcsetattr(target_fd, TCSAFLUSH, &target_termios) < 0) {
+		perror("initial tcsetattr on target");
+		exit(1);
+	}
+	return 0;
+}
+
+set_serial_nonblock(state)
+	int state;
+{
+	ioctl(target_fd, FIONBIO, &state);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/packetrx.c	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,74 @@
+/*
+ * This module handles the lowest level of serial packet Rx
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "pktmux.h"
+
+extern int target_fd;
+
+#define	MAXPKT	512
+u_char rxpkt[MAXPKT];
+size_t rxpkt_len;
+
+static int in_pkt, dle_state, toobig;
+
+static void
+process_inbyte(inb)
+{
+	if (!in_pkt) {
+		if (inb != STX || dle_state) {
+			dle_state = (inb == DLE);
+			return;
+		}
+		in_pkt = 1;
+		rxpkt_len = 0;
+		toobig = 0;
+		return;
+	}
+	if (dle_state) {
+		dle_state = 0;
+		if (inb != STX && inb != DLE) {
+			printf("Rx framing error: %02X after DLE\n", inb);
+			in_pkt = 0;
+			return;
+		}
+		goto data;
+	}
+	if (inb == DLE) {
+		dle_state = 1;
+		return;
+	} else if (inb == STX) {
+		if (!rxpkt_len)
+			return;
+		in_pkt = 0;
+		handle_rx_packet();
+		return;
+	}
+data:	if (rxpkt_len >= MAXPKT) {
+		if (!toobig) {
+			printf("Rx packet too big!\n");
+			toobig = 1;
+		}
+		return;
+	}
+	rxpkt[rxpkt_len++] = inb;
+}
+
+void
+process_serial_rx()
+{
+	u_char rdbuf[512];
+	int cc, i;
+
+	cc = read(target_fd, rdbuf, sizeof rdbuf);
+	if (cc <= 0) {
+		perror("Error/EOF reading from target");
+		exit(1);
+	}
+	for (i = 0; i < cc; i++)
+		process_inbyte(rdbuf[i]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/pktmux.h	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,16 @@
+/*
+ * Definitions for the RVT MUX over-the-wire protocol
+ */
+
+#define	STX	0x02
+#define	DLE	0x10
+
+#define RVT_RV_HEADER        0x11
+#define RVT_L1_HEADER        0x12
+#define RVT_L23_HEADER       0x13
+#define RVT_TM_HEADER        0x14
+#define RVT_RNET_HEADER      0x15
+#define RVT_PROF_HEADER      0x16
+#define RVT_GTTBACK_HEADER   0x17
+#define RVT_OTHER_HEADER     0x18
+#define RVT_INVALID_HEADER   0xFF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/rvtdump.c	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,62 @@
+/*
+ * This program reads bytes from a serial port, parses them assuming
+ * TI's RVT MUX format, and prints every decoded packet.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern int target_fd;
+extern char *baudrate_name;
+
+main(argc, argv)
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int c;
+	fd_set fds;
+
+	while ((c = getopt(argc, argv, "b:d:")) != EOF)
+		switch (c) {
+		case 'b':
+			baudrate_name = optarg;
+			continue;
+		case 'd':
+			target_fd = atoi(optarg);
+			continue;
+		case '?':
+		default:
+usage:			fprintf(stderr,
+			"usage: %s [-b baudrate] ttyport\n", argv[0]);
+			exit(1);
+		}
+	if (target_fd <= 0) {
+		if (argc - optind != 1)
+			goto usage;
+		open_target_serial(argv[optind]);
+	}
+
+	set_serial_nonblock(0);
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		c = select(target_fd+1, &fds, 0, 0, 0);
+		if (c < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (FD_ISSET(target_fd, &fds))
+			process_serial_rx();
+	}
+}
+
+handle_rx_packet()
+{
+	print_rx_packet();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/trdump.c	Thu Oct 31 19:59:16 2013 +0000
@@ -0,0 +1,77 @@
+/*
+ * This module implements the basic dump of any incoming packets
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "pktmux.h"
+
+extern u_char rxpkt[];
+extern size_t rxpkt_len;
+
+void
+print_presumed_string(str, len)
+	u_char *str;
+	size_t len;
+{
+	int i, c;
+
+	for (i = 0; i < len; i++) {
+		c = str[i];
+		if (c & 0x80) {
+			putchar('M');
+			putchar('-');
+			c &= 0x7F;
+		}
+		if (c < 0x20) {
+			putchar('^');
+			putchar(c + '@');
+		} else if (c == 0x7F) {
+			putchar('^');
+			putchar('?');
+		} else
+			putchar(c);
+	}
+}
+
+void
+print_rv_trace()
+{
+	int i;
+
+	/* the SWE static ID is sent MSB first */
+	for (i = 1; i <= 4; i++)
+		printf("%02X", rxpkt[i]);
+	/* severity level */
+	printf(" %d ", rxpkt[5]);
+	print_presumed_string(rxpkt + 6, rxpkt_len - 6);
+	putchar('\n');
+}
+
+void
+print_l1_trace()
+{
+	fputs("L1: ", stdout);
+	print_presumed_string(rxpkt + 1, rxpkt_len - 1);
+	putchar('\n');
+}
+
+void
+print_rx_packet()
+{
+	int i;
+
+	switch (rxpkt[0]) {
+	case RVT_RV_HEADER:
+		print_rv_trace();
+		return;
+	case RVT_L1_HEADER:
+		print_l1_trace();
+		return;
+	}
+	/* default case: print the whole packet in hex as an unknown */
+	fputs("UNK:", stdout);
+	for (i = 0; i < rxpkt_len; i++)
+		printf(" %02X", rxpkt[i]);
+	putchar('\n');
+}