Merge pull request #512 from g-oikonomou/contrib/tools/serialdump

Harmonize tools dir and the login, serialdump, serialview targets
This commit is contained in:
Simon Duquennoy 2018-05-27 15:39:30 +02:00 committed by GitHub
commit 2605a5174c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 259 additions and 710 deletions

5
.gitignore vendored
View File

@ -17,8 +17,9 @@ Makefile.target
Makefile.*.defines
tools/doxygen/html
patches-*
tools/tunslip
tools/tunslip6
tools/serial-io/tunslip6
tools/serial-io/serialdump
serialdump-*
build
tools/coffee-manager/build/
tools/coffee-manager/coffee.jar

33
Makefile.embedded Normal file
View File

@ -0,0 +1,33 @@
# This Makefile contains make variables and rules that are only applicable
# to builds for embedded devices (i.e. excluding platforms native and cooja).
# Future extensions to the build system that are of a similar nature (for
# embedded devices only), can be achieved by extending this Makefile here.
RLWRAPGOALS = login serialdump serialview
.PHONY: $(RLWRAPGOALS)
BAUDRATE ?= 115200
SERIALDUMP_TIME_FMT ?=
ifeq ($(HOST_OS),Windows)
SERIALDUMP = $(SERIAL_DUMP_BIN)
else
RLWRAP = $(notdir $(shell which rlwrap))
ifeq ($(RLWRAP),)
ifneq ($(filter $(RLWRAPGOALS),$(MAKECMDGOALS)),)
$(info Running serialdump without rlwrap support.)
$(info Consider installing rlwarp in order to be able to use command history)
endif
endif
SERIALDUMP = $(RLWRAP) $(SERIAL_DUMP_BIN)
endif
serialdump: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT) | tee serialdump-`date +%Y%m%d-%H%M`
serialview: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT)
login: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) $(PORT)

View File

@ -1,3 +1,8 @@
# This Makefile can be used to identify the selected TARGET used for a
# specific build. It can be included by example Makefiles that need to take
# decisions based on TARGET. It is also automatically included by the
# top-level Makefile.include.
ifeq ($(TARGET),)
-include Makefile.target
ifeq ($(TARGET),)

View File

@ -10,6 +10,9 @@ WERROR ?= 1
include $(CONTIKI)/Makefile.identify-target
### Include Makefile.tools to pull in targets that allow us to build tools dir
include $(CONTIKI)/Makefile.tools
CONTIKI_NG_TARGET_LIB = contiki-ng-$(TARGET).a
ifeq ($(DEFINES),)
@ -393,7 +396,7 @@ endif
usage:
@echo "Usage:"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [target]"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [PORT=(PORT)] [target]"
@echo ""
@echo "Typical usage:"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [all]"
@ -414,6 +417,9 @@ usage:
@echo " %.o Produces an object file from a given source file (e.g. hello-world.o)"
@echo " %.e Produces the pre-processed version of a given source file (e.g. hello-world.e)"
@echo " %.s Produces an assembly file from a given source file (e.g. hello-world.s)"
@echo " login View the serial output of the device connected to PORT"
@echo " serialview Same as login, but prepend serial output with a unix timestamp"
@echo " serialdump same as serialview, but also save the output to a file"
help: usage
@ -459,6 +465,12 @@ endif
@echo "To view more Make variables, edit $(CONTIKI)/Makefile.include, rule 'viewconf'"
@echo "To view more C variables, edit $(CONTIKI)/tools/viewconf.c"
### Include Makefile.embedded for relevant platforms, in order to pull in
### rules for login, serialview etc
ifeq ($(findstring $(TARGET),native cooja),)
include $(CONTIKI)/Makefile.embedded
endif
# Don't treat %.$(TARGET) as an intermediate file because it is
# in fact the primary target.
.PRECIOUS: %.$(TARGET)

17
Makefile.tools Normal file
View File

@ -0,0 +1,17 @@
# Some make rules in the main build system depend on the presence of utilities
# under the tools/ dir. For those dependencies, we use this makefile here to
# recursively invoke the respective build under tools/.
TOOLS_DIR = $(CONTIKI)/tools
SERIAL_IO_TOOL_DIR = $(TOOLS_DIR)/serial-io
SERIAL_IO_TOOL_DEPS = $(addprefix $(SERIAL_IO_TOOL_DIR)/, tools-utils.c tools-utils.h)
TUNSLIP6 = $(SERIAL_IO_TOOL_DIR)/tunslip6
SERIAL_DUMP_BIN = $(SERIAL_IO_TOOL_DIR)/serialdump
$(SERIAL_DUMP_BIN): $(SERIAL_IO_TOOL_DIR)/serialdump.c $(SERIAL_IO_TOOL_DEPS)
make -C $(SERIAL_IO_TOOL_DIR) serialdump
$(TUNSLIP6): $(SERIAL_IO_TOOL_DIR)/tunslip6.c $(SERIAL_IO_TOOL_DEPS)
make -C $(SERIAL_IO_TOOL_DIR) tunslip6

View File

@ -88,21 +88,7 @@ else
@echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target."
endif
# Check if we are running under Windows
ifeq ($(HOST_OS),Windows)
SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows
else
ifeq ($(HOST_OS),Darwin)
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-macos
else
# Else assume Linux
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-linux
endif
endif
UART_BAUDRATE = 115200
login:
$(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT)
### For the login etc targets
BAUDRATE = 115200
include $(CONTIKI)/arch/cpu/arm/cortex-m/cm3/Makefile.cm3

View File

@ -175,17 +175,14 @@ MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py
ifeq ($(HOST_OS),Windows)
USBDEVPREFIX=/dev/com
USBDEVBASENAME=COM
SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-windows
else
ifeq ($(HOST_OS),Darwin)
USBDEVPREFIX=
USBDEVBASENAME=/dev/tty.usbserial-
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-macos
else
# Else we assume Linux
USBDEVPREFIX=
USBDEVBASENAME=/dev/ttyUSB
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-linux
endif
endif
@ -195,7 +192,7 @@ ifndef MOTE
$(error MOTE not defined! You must specify which MOTE (serial port) to use)
endif
endif
PORT = $(USBDEVBASENAME)$(MOTE)
DEV_PORT = $(USBDEVBASENAME)$(MOTE)
#### make targets
@ -255,19 +252,19 @@ endif
### Upload target to one jn516x mote specified by MOTE=portNumber
ifeq ($(HOST_OS),Windows)
%.upload: %.$(TARGET).bin
${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $<
${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $<
else
%.upload: %.$(TARGET).bin
${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -f $<
${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -f $<
endif
### Flash the given file
ifeq ($(HOST_OS),Windows)
%.flash: ${FLASH_PROGRAMMER}
${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $*.$(TARGET).bin
${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $*.$(TARGET).bin
else
%.flash: ${FLASH_PROGRAMMER}
${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin
${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin
endif
### List the ports with connected jn516x motes
@ -297,19 +294,6 @@ serialdumpall:
### UART_BAUDRATE: i.e., 115200. default is 1000000
### example: make TARGET=jn516x UART_BAUDRATE=115200 login MOTE=1
UART_BAUDRATE ?= 1000000
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
($(MAKE) -C $(CONTIKI)/tools tunslip6 CFLAGS= LDFLAGS= LDLIBS= INCFLAGS=)
$(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c
(cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP)))
login: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT)
serialview: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp
serialdump: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp | tee serialdump-$(notdir $(PORT))-`date +%Y%m%d-%H%M`
### For the login etc targets
BAUDRATE = 1000000
PORT = $(USBDEVPREFIX)$(DEV_PORT)

View File

@ -54,7 +54,6 @@ else
ifeq ($(HOST_OS),Darwin)
ifndef MOTELIST
USBDEVPREFIX=
SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-macos
MOTELIST = $(CONTIKI)/tools/sky/motelist-macos
TMOTE_BSL_FILE = tmote-bsl-linux
TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0)
@ -75,7 +74,6 @@ else
# Else we assume Linux
ifndef MOTELIST
USBDEVPREFIX=
SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-linux
MOTELIST = $(CONTIKI)/tools/sky/motelist-linux
TMOTE_BSL_FILE = tmote-bsl-linux
TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0)
@ -171,21 +169,7 @@ $(CONTIKI)/tools/tunslip:
(cd $(CONTIKI)/tools; $(MAKE) tunslip)
ifdef MOTE
serialdump:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M`
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES))
PORT = $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES))
else
serialdump:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M`
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES))
PORT = $(USBDEVPREFIX)$(firstword $(CMOTES))
endif

View File

@ -56,11 +56,9 @@ ifeq ($(HOST_OS),Darwin)
USBDEVPREFIX=
MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia-macos
MOTES := $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,)
SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-macos
else
### If we are not running under Mac, we assume Linux
USBDEVPREFIX=
SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-linux
MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia
MOTES := $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \
perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);')
@ -103,8 +101,6 @@ zoul-motelist:
zoul-motes:
@echo $(MOTES)
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES))
### For the login etc targets
BAUDRATE = 115200
PORT = $(USBDEVPREFIX)$(firstword $(MOTES))

View File

@ -1,9 +1,7 @@
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
(cd $(CONTIKI)/tools && $(MAKE) tunslip6)
PREFIX ?= fd00::1/64
connect-router: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 $(PREFIX)
connect-router-cooja: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX)
connect-router: $(TUNSLIP6)
sudo $(TUNSLIP6) $(PREFIX)
connect-router-cooja: $(TUNSLIP6)
sudo $(TUNSLIP6) -a 127.0.0.1 $(PREFIX)

View File

@ -25,7 +25,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
TOOLS=tools tools/sky tools/jn516x
TOOLS=tools/serial-io
BASEDIR=../../
TESTLOGS=$(subst /,__,$(patsubst %,%.testlog, $(TOOLS)))

View File

@ -1,8 +0,0 @@
all: tunslip6
CFLAGS += -Wall -Werror
tunslip6: tools-utils.c tunslip6.c
clean:
rm -f *.o tunslip6

View File

@ -1,30 +0,0 @@
ifndef HOST_OS
ifeq ($(OS),Windows_NT)
HOST_OS := Windows
else
HOST_OS := $(shell uname)
endif
endif
ifeq ($(HOST_OS),Windows)
SERIALDUMP = serialdump-windows
endif
ifeq ($(HOST_OS),Darwin)
SERIALDUMP = serialdump-macos
endif
ifndef SERIALDUMP
# Assume Linux
SERIALDUMP = serialdump-linux
endif
all: $(SERIALDUMP)
CFLAGS += -Wall -Werror
$(SERIALDUMP): serialdump.c
$(CC) -O2 -o $@ $<
clean:
rm -f $(SERIALDUMP)

Binary file not shown.

View File

@ -1,396 +0,0 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BAUDRATE B115200
#define BAUDRATE_S "115200"
#ifdef linux
#define MODEMDEVICE "/dev/ttyS0"
#else
#define MODEMDEVICE "/dev/com1"
#endif /* linux */
#define SLIP_END 0300
#define SLIP_ESC 0333
#define SLIP_ESC_END 0334
#define SLIP_ESC_ESC 0335
#define CSNA_INIT 0x01
#define BUFSIZE 40
#define HCOLS 20
#define ICOLS 18
#define MODE_START_DATE 0
#define MODE_DATE 1
#define MODE_START_TEXT 2
#define MODE_TEXT 3
#define MODE_INT 4
#define MODE_HEX 5
#define MODE_SLIP_AUTO 6
#define MODE_SLIP 7
#define MODE_SLIP_HIDE 8
static unsigned char rxbuf[2048];
static int
usage(int result)
{
printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n");
printf(" -x for hexadecimal output\n");
printf(" -i for decimal output\n");
printf(" -s for automatic SLIP mode\n");
printf(" -so for SLIP only mode (all data is SLIP packets)\n");
printf(" -sn to hide SLIP packages\n");
printf(" -T[format] to add time for each text line\n");
printf(" (see man page for strftime() for format description)\n");
return result;
}
static void
print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index)
{
int i;
printf("\r%s", prefix);
for(i = 0; i < index; i++) {
if((i % 4) == 0) {
printf(" ");
}
printf("%02X", outbuf[i] & 0xFF);
}
printf(" ");
for(i = index; i < HCOLS; i++) {
if((i % 4) == 0) {
printf(" ");
}
printf(" ");
}
for(i = 0; i < index; i++) {
if(outbuf[i] < 30 || outbuf[i] > 126) {
printf(".");
} else {
printf("%c", outbuf[i]);
}
}
}
int
main(int argc, char **argv)
{
struct termios options;
fd_set mask, smask;
int fd;
speed_t speed = BAUDRATE;
char *speedname = BAUDRATE_S;
char *device = MODEMDEVICE;
char *timeformat = NULL;
unsigned char buf[BUFSIZE], outbuf[HCOLS];
unsigned char mode = MODE_START_TEXT;
int nfound, flags = 0;
unsigned char lastc = '\0';
int index = 1;
while(index < argc) {
if(argv[index][0] == '-') {
switch(argv[index][1]) {
case 'b':
/* set speed */
if(strcmp(&argv[index][2], "38400") == 0) {
speed = B38400;
speedname = "38400";
} else if(strcmp(&argv[index][2], "19200") == 0) {
speed = B19200;
speedname = "19200";
} else if(strcmp(&argv[index][2], "57600") == 0) {
speed = B57600;
speedname = "57600";
} else if(strcmp(&argv[index][2], "115200") == 0) {
speed = B115200;
speedname = "115200";
} else if(strcmp(&argv[index][2], "230400") == 0) {
speed = B230400;
speedname = "230400";
} else if(strcmp(&argv[index][2], "460800") == 0) {
speed = B460800;
speedname = "460800";
} else if(strcmp(&argv[index][2], "500000") == 0) {
speed = B500000;
speedname = "500000";
} else if(strcmp(&argv[index][2], "576000") == 0) {
speed = B576000;
speedname = "576000";
} else if(strcmp(&argv[index][2], "921600") == 0) {
speed = B921600;
speedname = "921600";
} else if(strcmp(&argv[index][2], "1000000") == 0) {
speed = B1000000;
speedname = "1000000";
} else {
fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]);
return usage(1);
}
break;
case 'x':
mode = MODE_HEX;
break;
case 'i':
mode = MODE_INT;
break;
case 's':
switch(argv[index][2]) {
case 'n':
mode = MODE_SLIP_HIDE;
break;
case 'o':
mode = MODE_SLIP;
break;
default:
mode = MODE_SLIP_AUTO;
break;
}
break;
case 'T':
if(strlen(&argv[index][2]) == 0) {
timeformat = "%Y-%m-%d %H:%M:%S";
} else {
timeformat = &argv[index][2];
}
mode = MODE_START_DATE;
break;
case 'h':
return usage(0);
default:
fprintf(stderr, "unknown option '%c'\n", argv[index][1]);
return usage(1);
}
index++;
} else {
device = argv[index++];
if(index < argc) {
fprintf(stderr, "too many arguments\n");
return usage(1);
}
}
}
fprintf(stderr, "connecting to %s (%s)", device, speedname);
#ifdef O_SYNC
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY /*| O_DIRECT*/ | O_SYNC);
if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian)
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT);
}
#else
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC );
#endif
if(fd < 0) {
fprintf(stderr, "\n");
perror("open");
exit(-1);
}
fprintf(stderr, " [OK]\n");
if(fcntl(fd, F_SETFL, 0) < 0) {
perror("could not set fcntl");
exit(-1);
}
if(tcgetattr(fd, &options) < 0) {
perror("could not get options");
exit(-1);
}
/* fprintf(stderr, "serial options set\n"); */
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
/* Enable the receiver and set local mode */
options.c_cflag |= (CLOCAL | CREAD);
/* Mask the character size bits and turn off (odd) parity */
options.c_cflag &= ~(CSIZE | PARENB | PARODD);
/* Select 8 data bits */
options.c_cflag |= CS8;
/* Raw input */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* Raw output */
options.c_oflag &= ~OPOST;
if(tcsetattr(fd, TCSANOW, &options) < 0) {
perror("could not set options");
exit(-1);
}
/* Make read() return immediately */
/* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */
/* perror("\ncould not set fcntl"); */
/* exit(-1); */
/* } */
FD_ZERO(&mask);
FD_SET(fd, &mask);
FD_SET(fileno(stdin), &mask);
index = 0;
for(;;) {
smask = mask;
nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
if(nfound < 0) {
if(errno == EINTR) {
fprintf(stderr, "interrupted system call\n");
continue;
}
/* something is very wrong! */
perror("select");
exit(1);
}
if(FD_ISSET(fileno(stdin), &smask)) {
/* data from standard in */
int n = read(fileno(stdin), buf, sizeof(buf));
if(n < 0) {
perror("could not read");
exit(-1);
} else if(n > 0) {
/* because commands might need parameters, lines needs to be
separated which means the terminating LF must be sent */
/* while(n > 0 && buf[n - 1] < 32) { */
/* n--; */
/* } */
if(n > 0) {
int i;
/* fprintf(stderr, "SEND %d bytes\n", n);*/
/* write slowly */
for(i = 0; i < n; i++) {
if(write(fd, &buf[i], 1) <= 0) {
perror("write");
exit(1);
} else {
fflush(NULL);
usleep(6000);
}
}
}
} else {
/* End of input, exit. */
exit(0);
}
}
if(FD_ISSET(fd, &smask)) {
int i, j, n = read(fd, buf, sizeof(buf));
if(n < 0) {
perror("could not read");
exit(-1);
}
for(i = 0; i < n; i++) {
switch(mode) {
case MODE_START_TEXT:
case MODE_TEXT:
printf("%c", buf[i]);
break;
case MODE_START_DATE: {
time_t t;
t = time(&t);
strftime(outbuf, HCOLS, timeformat, localtime(&t));
printf("%s|", outbuf);
mode = MODE_DATE;
}
/* continue into the MODE_DATE */
case MODE_DATE:
printf("%c", buf[i]);
if(buf[i] == '\n') {
mode = MODE_START_DATE;
}
break;
case MODE_INT:
printf("%03d ", buf[i]);
if(++index >= ICOLS) {
index = 0;
printf("\n");
}
break;
case MODE_HEX:
rxbuf[index++] = buf[i];
if(index >= HCOLS) {
print_hex_line("", rxbuf, index);
index = 0;
printf("\n");
}
break;
case MODE_SLIP_AUTO:
case MODE_SLIP_HIDE:
if(!flags && (buf[i] != SLIP_END)) {
/* Not a SLIP packet? */
printf("%c", buf[i]);
break;
}
/* continue to slip only mode */
case MODE_SLIP:
switch(buf[i]) {
case SLIP_ESC:
lastc = SLIP_ESC;
break;
case SLIP_END:
if(index > 0) {
if(flags != 2 && mode != MODE_SLIP_HIDE) {
/* not overflowed: show packet */
print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index);
printf("\n");
}
lastc = '\0';
index = 0;
flags = 0;
} else {
flags = !flags;
}
break;
default:
if(lastc == SLIP_ESC) {
lastc = '\0';
/* Previous read byte was an escape byte, so this byte will be
interpreted differently from others. */
switch(buf[i]) {
case SLIP_ESC_END:
buf[i] = SLIP_END;
break;
case SLIP_ESC_ESC:
buf[i] = SLIP_ESC;
break;
}
}
rxbuf[index++] = buf[i];
if(index >= sizeof(rxbuf)) {
fprintf(stderr, "**** slip overflow\n");
index = 0;
flags = 2;
}
break;
}
break;
}
}
/* after processing for some output modes */
if(index > 0) {
switch(mode) {
case MODE_HEX:
print_hex_line("", rxbuf, index);
break;
}
}
fflush(stdout);
}
}
}

13
tools/serial-io/Makefile Normal file
View File

@ -0,0 +1,13 @@
APPS = tunslip6 serialdump
LIB_SRCS = tools-utils.c
DEPEND = tools-utils.h
all: $(APPS)
CFLAGS += -Wall -Werror -O2
$(APPS) : % : %.c $(LIB_SRCS) $(DEPEND)
$(CC) $(CFLAGS) $< $(LIB_SRCS) -o $@
clean:
rm -f $(APPS)

View File

@ -1,4 +1,7 @@
#define _GNU_SOURCE
/*---------------------------------------------------------------------------*/
#include "tools-utils.h"
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
@ -9,15 +12,18 @@
#include <string.h>
#include <time.h>
#include <signal.h>
/*---------------------------------------------------------------------------*/
#define BAUDRATE B115200
#define BAUDRATE_S "115200"
speed_t b_rate = BAUDRATE;
/*---------------------------------------------------------------------------*/
#ifdef linux
#define MODEMDEVICE "/dev/ttyS0"
#else
#define MODEMDEVICE "/dev/com1"
#endif /* linux */
/*---------------------------------------------------------------------------*/
#define SLIP_END 0300
#define SLIP_ESC 0333
#define SLIP_ESC_END 0334
@ -38,13 +44,19 @@
#define MODE_SLIP_AUTO 6
#define MODE_SLIP 7
#define MODE_SLIP_HIDE 8
/*---------------------------------------------------------------------------*/
#ifndef O_SYNC
#define O_SYNC 0
#endif
#define OPEN_FLAGS (O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC)
/*---------------------------------------------------------------------------*/
static unsigned char rxbuf[2048];
/*---------------------------------------------------------------------------*/
static int
usage(int result)
{
printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n");
printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] T[format] [SERIALDEVICE]\n");
printf(" -x for hexadecimal output\n");
printf(" -i for decimal output\n");
printf(" -s for automatic SLIP mode\n");
@ -54,7 +66,7 @@ usage(int result)
printf(" (see man page for strftime() for format description)\n");
return result;
}
/*---------------------------------------------------------------------------*/
static void
print_hex_line(char *prefix, unsigned char *outbuf, int index)
{
@ -82,13 +94,13 @@ print_hex_line(char *prefix, unsigned char *outbuf, int index)
}
}
}
/*---------------------------------------------------------------------------*/
static void
intHandler(int sig)
{
exit(0);
}
/*---------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
@ -97,8 +109,7 @@ main(int argc, char **argv)
struct termios options;
fd_set mask, smask;
int fd;
speed_t speed = BAUDRATE;
char *speedname = BAUDRATE_S;
int baudrate = BUNKNOWN;
char *device = MODEMDEVICE;
char *timeformat = NULL;
unsigned char buf[BUFSIZE];
@ -111,57 +122,41 @@ main(int argc, char **argv)
while(index < argc) {
if(argv[index][0] == '-') {
switch(argv[index][1]) {
case 'b':
/* set speed */
if(strcmp(&argv[index][2], "38400") == 0) {
speed = B38400;
speedname = "38400";
} else if(strcmp(&argv[index][2], "19200") == 0) {
speed = B19200;
speedname = "19200";
} else if(strcmp(&argv[index][2], "57600") == 0) {
speed = B57600;
speedname = "57600";
} else if(strcmp(&argv[index][2], "115200") == 0) {
speed = B115200;
speedname = "115200";
} else {
fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]);
return usage(1);
}
case 'b':
baudrate = atoi(&argv[index][2]);
break;
case 'x':
mode = MODE_HEX;
break;
case 'i':
mode = MODE_INT;
break;
case 's':
switch(argv[index][2]) {
case 'n':
mode = MODE_SLIP_HIDE;
break;
case 'x':
mode = MODE_HEX;
case 'o':
mode = MODE_SLIP;
break;
case 'i':
mode = MODE_INT;
break;
case 's':
switch(argv[index][2]) {
case 'n':
mode = MODE_SLIP_HIDE;
break;
case 'o':
mode = MODE_SLIP;
break;
default:
mode = MODE_SLIP_AUTO;
break;
}
break;
case 'T':
if(strlen(&argv[index][2]) == 0) {
timeformat = "%Y-%m-%d %H:%M:%S";
} else {
timeformat = &argv[index][2];
}
mode = MODE_START_DATE;
break;
case 'h':
return usage(0);
default:
fprintf(stderr, "unknown option '%c'\n", argv[index][1]);
return usage(1);
mode = MODE_SLIP_AUTO;
break;
}
break;
case 'T':
if(strlen(&argv[index][2]) == 0) {
timeformat = "%Y-%m-%d %H:%M:%S";
} else {
timeformat = &argv[index][2];
}
mode = MODE_START_DATE;
break;
case 'h':
return usage(0);
default:
fprintf(stderr, "unknown option '%c'\n", argv[index][1]);
return usage(1);
}
index++;
} else {
@ -172,24 +167,19 @@ main(int argc, char **argv)
}
}
}
fprintf(stderr, "connecting to %s (%s)", device, speedname);
#ifndef O_SYNC
#define O_SYNC 0
#endif
#ifdef O_DIRECT
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC);
/* Some systems do not support certain parameters (e.g. raspbian)
* Just do some random testing. Not sure whether there is a better way
* of doing this. */
if(fd < 0 && errno == EINVAL){
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);
if(baudrate != BUNKNOWN) {
b_rate = select_baudrate(baudrate);
if(b_rate == 0) {
fprintf(stderr, "unknown baudrate %d\n", baudrate);
exit(-1);
}
}
#else
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);
#endif
fprintf(stderr, "connecting to %s", device);
fd = open(device, OPEN_FLAGS);
if(fd < 0) {
fprintf(stderr, "\n");
perror("open");
@ -206,9 +196,10 @@ main(int argc, char **argv)
perror("could not get options");
exit(-1);
}
/* fprintf(stderr, "serial options set\n"); */
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
cfsetispeed(&options, b_rate);
cfsetospeed(&options, b_rate);
/* Enable the receiver and set local mode */
options.c_cflag |= (CLOCAL | CREAD);
/* Mask the character size bits and turn off (odd) parity */
@ -228,12 +219,6 @@ main(int argc, char **argv)
exit(-1);
}
/* Make read() return immediately */
/* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */
/* perror("\ncould not set fcntl"); */
/* exit(-1); */
/* } */
FD_ZERO(&mask);
FD_SET(fd, &mask);
FD_SET(fileno(stdin), &mask);
@ -241,7 +226,7 @@ main(int argc, char **argv)
index = 0;
for(;;) {
smask = mask;
nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
nfound = select(FD_SETSIZE, &smask, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
if(nfound < 0) {
if(errno == EINTR) {
fprintf(stderr, "interrupted system call\n");
@ -260,7 +245,7 @@ main(int argc, char **argv)
exit(-1);
} else if(n > 0) {
/* because commands might need parameters, lines needs to be
separated which means the terminating LF must be sent */
separated which means the terminating LF must be sent */
/* while(n > 0 && buf[n - 1] < 32) { */
/* n--; */
/* } */
@ -298,103 +283,103 @@ main(int argc, char **argv)
for(i = 0; i < n; i++) {
switch(mode) {
case MODE_START_TEXT:
case MODE_TEXT:
printf("%c", buf[i]);
break;
case MODE_START_DATE: {
time_t t;
t = time(&t);
strftime(outbuf, HCOLS, timeformat, localtime(&t));
printf("%s|", outbuf);
mode = MODE_DATE;
case MODE_START_TEXT:
case MODE_TEXT:
printf("%c", buf[i]);
break;
case MODE_START_DATE: {
time_t t;
t = time(&t);
strftime(outbuf, HCOLS, timeformat, localtime(&t));
printf("[%s] ", outbuf);
mode = MODE_DATE;
}
/* continue into the MODE_DATE */
case MODE_DATE:
printf("%c", buf[i]);
if(buf[i] == '\n') {
mode = MODE_START_DATE;
}
/* continue into the MODE_DATE */
case MODE_DATE:
break;
case MODE_INT:
printf("%03d ", buf[i]);
if(++index >= ICOLS) {
index = 0;
printf("\n");
}
break;
case MODE_HEX:
rxbuf[index++] = buf[i];
if(index >= HCOLS) {
print_hex_line("", rxbuf, index);
index = 0;
printf("\n");
}
break;
case MODE_SLIP_AUTO:
case MODE_SLIP_HIDE:
if(!flags && (buf[i] != SLIP_END)) {
/* Not a SLIP packet? */
printf("%c", buf[i]);
if(buf[i] == '\n') {
mode = MODE_START_DATE;
}
break;
case MODE_INT:
printf("%03d ", buf[i]);
if(++index >= ICOLS) {
}
/* continue to slip only mode */
case MODE_SLIP:
switch(buf[i]) {
case SLIP_ESC:
lastc = SLIP_ESC;
break;
case SLIP_END:
if(index > 0) {
if(flags != 2 && mode != MODE_SLIP_HIDE) {
/* not overflowed: show packet */
print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index);
printf("\n");
}
lastc = '\0';
index = 0;
printf("\n");
flags = 0;
} else {
flags = !flags;
}
break;
case MODE_HEX:
default:
if(lastc == SLIP_ESC) {
lastc = '\0';
/* Previous read byte was an escape byte, so this byte will be
interpreted differently from others. */
switch(buf[i]) {
case SLIP_ESC_END:
buf[i] = SLIP_END;
break;
case SLIP_ESC_ESC:
buf[i] = SLIP_ESC;
break;
}
}
rxbuf[index++] = buf[i];
if(index >= HCOLS) {
print_hex_line("", rxbuf, index);
if(index >= sizeof(rxbuf)) {
fprintf(stderr, "**** slip overflow\n");
index = 0;
printf("\n");
}
break;
case MODE_SLIP_AUTO:
case MODE_SLIP_HIDE:
if(!flags && (buf[i] != SLIP_END)) {
/* Not a SLIP packet? */
printf("%c", buf[i]);
break;
}
/* continue to slip only mode */
case MODE_SLIP:
switch(buf[i]) {
case SLIP_ESC:
lastc = SLIP_ESC;
break;
case SLIP_END:
if(index > 0) {
if(flags != 2 && mode != MODE_SLIP_HIDE) {
/* not overflowed: show packet */
print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index);
printf("\n");
}
lastc = '\0';
index = 0;
flags = 0;
} else {
flags = !flags;
}
break;
default:
if(lastc == SLIP_ESC) {
lastc = '\0';
/* Previous read byte was an escape byte, so this byte will be
interpreted differently from others. */
switch(buf[i]) {
case SLIP_ESC_END:
buf[i] = SLIP_END;
break;
case SLIP_ESC_ESC:
buf[i] = SLIP_ESC;
break;
}
}
rxbuf[index++] = buf[i];
if(index >= sizeof(rxbuf)) {
fprintf(stderr, "**** slip overflow\n");
index = 0;
flags = 2;
}
break;
flags = 2;
}
break;
}
break;
}
}
/* after processing for some output modes */
if(index > 0) {
switch(mode) {
case MODE_HEX:
print_hex_line("", rxbuf, index);
break;
case MODE_HEX:
print_hex_line("", rxbuf, index);
break;
}
}
fflush(stdout);

View File

@ -30,7 +30,7 @@
*
*/
#include "tools-utils.h"
#include "tools-utils.h"
speed_t
select_baudrate(int baudrate) {
@ -159,4 +159,3 @@ select_baudrate(int baudrate) {
return 0;
}
}

View File

@ -35,6 +35,9 @@
#include <termios.h>
/* The unspecified baudrate */
#define BUNKNOWN -2
#if __APPLE__
#ifndef B460800
#define B460800 460800

View File

@ -1,30 +0,0 @@
ifndef HOST_OS
ifeq ($(OS),Windows_NT)
HOST_OS := Windows
else
HOST_OS := $(shell uname)
endif
endif
ifeq ($(HOST_OS),Windows)
SERIALDUMP = serialdump-windows
endif
ifeq ($(HOST_OS),Darwin)
SERIALDUMP = serialdump-macos
endif
ifndef SERIALDUMP
# Assume Linux
SERIALDUMP = serialdump-linux
endif
all: $(SERIALDUMP)
CFLAGS += -Wall -Werror
$(SERIALDUMP): serialdump.c
$(CC) -O2 -o $@ $<
clean:
rm -f $(SERIALDUMP)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +0,0 @@
#!/bin/sh
# We run perl through a shell to avoid having to hard-code the path to perl
perl -e '$|=1; while(<>) {print time . " $_";}'