如何监控串口流量?

Dee*_*pak 51 linux serial-port

有没有什么端口监控工具可以监视写在端口上的数据包?我特别想检查我用 Java 编写的程序是否有效,所以我需要某种工具来查看我的小应用程序是否正在将消息写入端口。我该怎么做呢?

Ale*_*ies 44

是一种将(几乎)所有东西连接到(几乎)所有东西的工具,并且可以复制流。
在您的用例中,您可以将您的串行端口连接/dev/ttyS0到 PTY /tmp/ttyV0,然后将您的应用程序指向 PTY,并在tee某处输出 Input 和 Output 供您观察。

谷歌搜索“socat serial port pty tee debug”将指向几个“标准程序”示例,其中一个是:

socat /dev/ttyS0,raw,echo=0 \
SYSTEM:'tee in.txt |socat - "PTY,link=/tmp/ttyV0,raw,echo=0,waitslave" |tee out.txt'
Run Code Online (Sandbox Code Playgroud)

这些文件in.txtout.txt随后将包含捕获的数据。

评论后更新:

  • socat 语法起初看起来很混乱,但实际上,它只是 2 个嵌套语句。
    为如此强大的多功能工具付出的代价很小。
  • 如果您需要设置串行端口,或发送其他 ioctl,请在调用 socat 之前进行,因为 socat 无法代理它们。
  • interceptty2006 年的单一用途工具的语法稍微简单一些,但只能拦截 TTY(在代理 ioctls 时),并且可能不在您的包管理器中。(大多数 Linux 发行版从未将其添加到他们的存储库中)


Gil*_*il' 21

我认为串行驱动程序没有任何跟踪功能可以让您查看数据包。您可以使用strace来观察应用程序中的所有读取和写入:

strace -s9999 -o myapp.strace -eread,write,ioctl ./myapp
Run Code Online (Sandbox Code Playgroud)


Sha*_*off 17

我找到了名为Linux Serial SnifferjpnevulatorMoni 的项目。前两个看起来就像他们做的正是你想要的。最后一个自称为监视器,但它实际上看起来像一个标准的串行通信程序。

  • «LInux Serial Sniffer» 有问题,它绝对会取出传入的数据,因此另一个实际监听串行的应用程序什么也看不到。但是,至少,外面的数据似乎没有问题。 (4认同)
  • 来自 [jpnevulator FAQ](https://jpnevulator.snarl.nl/src/current/FAQ):“Jpnevulator 从未被构建为位于内核和您的应用程序之间。” (3认同)
  • -1 因为 3 条评论:*LInux Serial Sniffer is buggy*,然后 *Jpnevulator 从未被构建为位于内核和应用程序之间* 并且最后 *Moni 已死*...这个答案只指向 3 个外部链接,不要t给出一个真正的解决方案。(3 个链接失败,没有留下任何东西!) (2认同)

Gol*_*lar 7

interceptty 做那个工作:

interceptty /dev/ttyACM0 /dev/ttyDUMMY
Run Code Online (Sandbox Code Playgroud)

或者,使用漂亮的输出格式和配置后端设备,并使用行缓冲:

interceptty -s 'ispeed 19200 ospeed 19200' -l /dev/ttyACM0 /dev/ttyDUMMY | interceptty-nicedump
Run Code Online (Sandbox Code Playgroud)

然后与您的程序连接到/dev/ttyDUMMY.


F. *_*uri 5

这是我最终选择的方式

谢吉尔斯的回答

strace -s 9999 -e read -ffp $(sed '/ttyUSB0/s/^.*proc.\([0-9]\+\).fd.*/\1/p;d' <(ls -l /proc/[1-9]*/fd/* 2>/dev/null)) 2>&1 | perl -e '$|=1;my %qa=('a'=>7,'b'=>10,'e'=>33,'f'=>14,'n'=>12,'r'=>15,'t'=>11);sub cnv { my $ch=$_[0];$ch=$qa[$1] if $ch=~/([abefnrt])/;return chr(oct($ch));  };while (<>) { /^read.\d+,\s+"(.*)",\s\d+.*$/ && do { $_=$1;s/\\(\d+|[abefnrt])/cnv($1)/eg;print; };};'
Run Code Online (Sandbox Code Playgroud)

对不起,我会解释...

#!/bin/bash

strace -s 9999 -e read -ffp $(
    sed "/tty${1:-USB0}/s/^.*proc.\([0-9]\+\).fd.*/\1/p;d" <(
        ls -l /proc/[1-9]*/fd/* 2>/dev/null
    )
) 2>&1 |
    perl -e '
        $|=1;
        my %qa=('a'=>7,'b'=>10,'e'=>33,'f'=>14,'n'=>12,'r'=>15,'t'=>11);
        sub cnv {
            my $ch=$_[0];
            $ch=$qa[$1] if $ch=~/([abefnrt])/;
            return chr(oct($ch));
        };
        while (<>) {
            /^read.\d+,\s+"(.*)",\s\d+.*$/ && do {
                $_=$1;
                s/\\(\d+|[abefnrt])/cnv($1)/eg;
                print;
            };
        };
    '
Run Code Online (Sandbox Code Playgroud)
  • 我使用ls -l /proc/[0-9]*/fd/* | grep ttyUSB0而不是lsof ttyUSB0因为我看到它们有时很慢。
  • 所以 strace 将使用 ttyUSB0
  • 语法:tty${1:-USB0}将允许,用作脚本或函数,以串行设备名称作为参数运行它们:ttySniff USB0ttySniff S0等等。
  • Perl 脚本将unbackslash字符串记录在strace -s 9999.
  • 你可以替换strace -e readstrace -e read,writestrace -e write根据您的需要。

注意:我使用语法运行它们:

 script -t ttySniff.log 2>ttySniff.tm -c "./ttySniff.sh USB0"
Run Code Online (Sandbox Code Playgroud)

所以我可以重播整个操作并跟踪计时执行。