# HG changeset patch # User Michael Spacefalcon # Date 1383249556 0 # Node ID 811b138f1bedb4621c87d2dd407e70c63fecb634 # Parent 17c1e2a38418509876d85f1bdf45d0f6063bd0a9 rvtdump utility written, compiles diff -r 17c1e2a38418 -r 811b138f1bed .hgignore --- 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/ diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/Makefile --- /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} diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/openport.c --- /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 +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/packetrx.c --- /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 +#include +#include +#include +#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]); +} diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/pktmux.h --- /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 diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/rvtdump.c --- /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 +#include +#include +#include +#include + +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(); +} diff -r 17c1e2a38418 -r 811b138f1bed rvinterf/trdump.c --- /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 +#include +#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'); +}