26
votes

I'm debugging communications with a serial device, and I need to see all the data flowing both directions.

It seems like this should be easy on Linux, where the serial port is represented by a file. Is there some way that I can do a sort of "bi-directional tee", where I tell my program to connect to a pipe that copies the data to a file and also shuffles it to/from the actual serial port device?

I think I might even know how to write such a beast, but it seems non-trivial, especially to get all of the ioctls passed through for port configuration, etc.

Has anyone already built such a thing? It seems too useful (for people debugging serial device drivers) not to exist already.

5
So... how did you end up doing this, exactly?detly
Yep, I would be interested in knowing too, as I failed so far to understand how to use strace for this. Cheers!mac
This might be of interest to those that struggled with the given answer: unix.stackexchange.com/questions/12359/…geekboyUK

5 Answers

23
votes

strace is very useful for this. You have a visualisation of all ioctl calls, with the corresponding structure decoded. The following options seems particularly useful in your case:

-e read=set

Perform a full hexadecimal and ASCII dump of all the data read from file descriptors listed in the specified set. For example, to see all input activity on file descriptors 3 and 5 use -e read=3,5. Note that this is independent from the normal tracing of the read(2) system call which is controlled by the option -e trace=read.

-e write=set

Perform a full hexadecimal and ASCII dump of all the data written to file descriptors listed in the specified set. For example, to see all output activity on file descriptors 3 and 5 use -e write=3,5. Note that this is independent from the normal tracing of the write(2) system call which is controlled by the option -e trace=write.

4
votes

I have found pyserial to be quite usable, so if you're into Python it shouldn't be too hard to write such a thing.

2
votes

A simple method would be to write an application which opened the master side of a pty and the tty under test. You would then pass your tty application the slave side of the pty as the 'tty device'.

You would have to monitor the pty attributes with tcgetattr() on the pty master and call tcsetattr() on the real tty, if the attributes changed.

The rest would be a simple select() on both fd's copying data bi-directionally and copying it to a log.

2
votes

I looked at a lot of serial sniffers. All of them are based on the idea of making a virtual serial port and sniff data from that port. However, any baud/parity/flow changes will break connection.

So, I wrote my own sniffer :). Most of the serial ports now are just USB-to-serial converters. My sniffer collects data from USB through debugfs, parse it and output to the console. Also any baudrate changes, flow control, line events, and serial errors are also recorded. The project is in the early stage of development and for now, only FTDI is supported.

http://code.google.com/p/uscmon/

0
votes

Much like @MBR, I was looking into serial sniffers, but the ptys broke the parity check. However, his sniffer was not helping me, as I'm using a CP2102, and not a FT232. So I wrote my own sniffer, by following this, and now I have one that can record file I/O on arbitrary files: I called it tracie.