Как я могу отслеживать трафик последовательного порта?

Вопрос или проблема

Есть ли какой-либо инструмент для мониторинга порта, чтобы отслеживать пакеты, записываемые на порт? Я особенно хочу проверить, работает ли моя программа, написанная на Java, поэтому мне нужен какой-то инструмент, чтобы увидеть, пишет ли моё небольшое приложение сообщения в порт. Как мне это сделать?

— это инструмент для подключения (практически) всего к (практически) всему, и может дублировать потоки. В вашем случае вы можете подключить свой последовательный порт /dev/ttyS0 к PTY /tmp/ttyV0, затем указать вашему приложению использовать PTY и позволить socat tee выводить введенные и выходные данные, чтобы вы могли их наблюдать.

Поиск в Google “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'

Файлы in.txt и out.txt будут содержать захваченные данные.

Обновлено после комментариев:

  • Синтаксис socat может сначала показаться запутанным, но на самом деле это просто два вложенных выражения.
    Небольшая плата за такой мощный и универсальный инструмент.
  • Если вам нужно настроить свой последовательный порт или отправить другие ioctls, сделайте это перед вызовом socat, так как socat не может их проксировать.
  • Одноцелевой инструмент interceptty 2006 года имеет несколько более простой синтаксис, но может перехватывать только TTY (проксируя ioctls) и, вероятно, не доступен в вашем менеджере пакетов. (Большинство дистрибутивов Linux никогда не добавляли его в свои репозитории.)

Я не думаю, что драйвер последовательного порта имеет какие-либо функции трассировки, которые позволили бы вам наблюдать за пакетами. Вы можете использовать strace, чтобы наблюдать за всеми чтениями и записями вашего приложения:

strace -s9999 -o myapp.strace -eread,write,ioctl ./myapp

Я нашел проекты под названием Linux Serial Sniffer, jpnevulator, и Moni (Редактировать: Обновленная ссылка). Первые два, похоже, делают именно то, что вам нужно. Последний называет себя монитором, но на самом деле выглядит как стандартная программа последовательной связи.

interceptty выполняет эту работу:

interceptty /dev/ttyACM0 /dev/ttyDUMMY

или, с приятным форматом вывода и конфигурацией заднего устройства, и с буферизацией по строкам:

interceptty -s 'ispeed 19200 ospeed 19200' -l /dev/ttyACM0 /dev/ttyDUMMY | interceptty-nicedump

а затем подключите свою программу к /dev/ttyDUMMY.

Это то, что я в конечном итоге выбрал

Спасибо ответу Гилла! Вот моя последняя команда, чтобы шпионить за действиями на RS232:

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)) |& 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; };};'

В качестве скрипта ttySniff:

#!/bin/bash

read -r tPid tFd < <(
    sed -ne < <(LANG=C /bin/ls -l /proc/[1-9]*/fd/* 2>/dev/null
    ) "s@^.*proc/\([0-9]\+\)/fd/\([0-9]\+\) -> /dev/tty${1:-USB0}\$@\1 \2@p"
)
(( tPid * tFd )) || exit 0

export tFd
strace -s 9999 -e ${2:-read} -ffp $tPid 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 (<>) {
            /^[[:alnum:]]*\($ENV{tFd},\s+"(.*)",\s\d+.*$/ && do {
                $_=$1;
                s/\\(\d{1,3}|[abefnrt])/cnv($1)/eg;
                print;
            };
        };
    '
  • Для поиска PID процесса, использующего ttyUSB0, используйте ls -l /proc/[0-9]*/fd/* | sed '/ttyUSB0/s/... вместо lsof ttyUSB0, потому что этот способ значительно быстрее (и lsof не установлен по умолчанию).
  • Таким образом, strace будет отслеживать текущую программу, использующую ttyUSB0.
  • Примечание: Используемый как скрипт или функция, синтаксис: tty${1:-USB0} позволит запускать их с именем последовательного устройства в качестве аргумента: ttySniff USB0 или ttySniff S0 и так далее.
  • Perl-скрипт будет разоблачать строки, зарегистрированные strace -s 9999.
  • Вы можете заменить strace -e read на strace -e read,write или strace -e write в зависимости от ваших нужд.

Примечание: Я запускаю их, используя следующий синтаксис:

 script -t ttySniff.log 2>ttySniff.tm -c "./ttySniff.sh USB0"

чтобы я мог воспроизвести всю операцию и отследить временные выполнения.

Когда я отлаживаю взаимодействие моего приложения с последовательным портом, я использую moserial.

Попробуйте это:

screen /dev/tty.usbserial-blahblah 9600

работает для меня.

minicom отсутствует в списке инструментов для мониторинга последовательных портов. Используйте его, например, чтобы прослушивать устройство arduino:

minicom --device /dev/ttyACM0 --baud 9600

Обратите внимание на ttyUSBSpy. Он находится на альфа-стадии, но работает.

Существует много ответов и подходов к этому, каждый из которых имеет разные свойства. Обычный — использование socat, как в ответе, приведенном выше Алекса, который также обсуждается в этом блоге.

Тем не менее, если вы предпочитаете создать отдельное устройство, которое будет только лишь версией для чтения оригинального устройства, как я, – скажем, чтобы открыть minicom на устройстве только для чтения и позволить другим программам взаимодействовать с устройством с правом чтения и записи нормально – я только что придумал следующее, что хорошо работает.

socat /dev/ttyUSB0,rawer SYSTEM:'tee >(socat - "PTY,link=/tmp/foobar-ro,rawer" >%-) | socat - "PTY,link=/tmp/foobar-rw,rawer,wait-slave"'

Это сложно, поэтому я немного разобью это. Логически это:

socat /dev/ttyUSB3,rawer SYSTEM:'tee [READ-ONLY PTY] | [READ-WRITE PTY]'

И это работает примерно так:

  1. Первая команда socat устанавливает двунаправленный канал между первым адресом (/dev/ttyUSB0) и вторым (команда SYSTEM).
  2. Теперь внутри команды SYSTEM tee дублирует свой stdin (т.е. вывод /dev/ttyUSB0) как в [READ-ONLY PTY], так и в свой собственный stdout, который мы затем передаём в [READ-WRITE PTY].
  3. [READ-ONLY PTY] создаётся с помощью второй команды socat, где первый адрес – это - (сокращение для типа адреса STDIO в socat), а второй – новое PTY. Мы также следим за тем, чтобы закрыть stdout этой 2-й команды socat с помощью >%-; это делает его только для чтения.
    • По какой-то причине, которую я не понимаю, если stdout 2-й socat не закрыт, tee, похоже, включает вывод из подстановки процесса в свой собственный вывод. Я не уверен, почему tee вообще читает свои аргументы.
  4. Наконец, [READ-WRITE PTY] создается с помощью третьей команды socat, аналогичной 2-й. Stdout этой 3-й socat становится выводом адреса SYSTEM из 1-й socat и поступает на вход оригинальному устройству, завершив цикл.

Ответ или решение

Как контролировать трафик последовательного порта: подробное руководство

Ваша задача по мониторингу трафика последовательного порта — это важный шаг для отладки и проверки работы ваших приложений, особенно если вы работаете с такими языками программирования, как Java. Давайте рассмотрим несколько эффективных способов для осуществления мониторинга последовательного порта, включая инструменты и методы, которые помогут вам увидеть, как ваша программа взаимодействует с портом.

1. Использование socat для мониторинга последовательного порта

Socat — это мощный инструмент для создания соединений между различными потоками данных. Его можно использовать для перенаправления трафика с последовательного порта в виртуальное псевдотерминальное устройство (PTY), что позволит вам наблюдать за данными, проходящими через порт.

Пример команды:
socat /dev/ttyS0,raw,echo=0 SYSTEM:'tee in.txt | socat - "PTY,link=/tmp/ttyV0,raw,echo=0,waitslave" | tee out.txt'

В этом примере:

  • /dev/ttyS0 — ваш последовательный порт.
  • in.txt и out.txt будут содержать входящие и исходящие данные соответственно.
  • /tmp/ttyV0 — виртуальное устройство, к которому вы можете подключить ваше Java-приложение.

Программа будет писать данные на /tmp/ttyV0, а вы сможете наблюдать за этими данными в файлах in.txt и out.txt.

2. Применение strace для отслеживания системных вызовов

Если ваше приложение написано на Java и вы хотите наблюдать за системными вызовами, связанными с чтением и записью в последовательный порт, strace станет отличным инструментом.

Пример команды:
strace -s9999 -o myapp.strace -eread,write,ioctl ./myapp

С помощью этой команды вы сможете увидеть, как ваше приложение взаимодействует с устройством. Вы можете фильтровать системные вызовы для read, write и ioctl, что позволит вам сосредоточиться на интересующих вас операциях.

3. Простые инструменты для мониторинга

  • minicom: Это инструмент, который позволяет вам взаимодействовать с последовательными устройствами. Например:

    minicom --device /dev/ttyACM0 --baud 9600

    Это создаст подключение к устройству /dev/ttyACM0 с установленной скоростью 9600 бод.

  • moserial: Графический интерфейс для мониторинга последовательных портов. Он позволяет легко настраивать параметры соединения и наблюдать за трафиком.

4. Альтернативные инструменты

Существуют и другие инструменты, такие как Linux Serial Sniffer, jpnevulator и ttyUSBSpy, которые могут подойти для мониторинга и анализа данных на последовательном порту. Их использование может быть ограничено спецификой вашего проекта, поэтому стоит ознакомиться с документами каждого из них.

5. Практический подход к отладке

Ниже приведен пример сценария, который может помочь вам автоматически находить PID и FD процесса, использующего последовательный порт:

#!/bin/bash

read -r tPid tFd < <(sed -ne "/ttyUSB0/s/^.*proc.\([0-9]\+\).fd.*/\1/p;d" <(ls -l /proc/[1-9]*/fd/* 2>/dev/null))
(( tPid * tFd )) || exit 0

export tFd
strace -s 9999 -e read -ffp $tPid 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 (<>){
        /^[[:alnum:]]*\($ENV{tFd},\s+"(.*)",\s\d+.*$/ && do { $_=$1; s/\\(\d{1,3}|[abefnrt])/cnv($1)/eg; print; };
    };
'

Этот скрипт позволит вам автоматически собирать данные о процессе, взаимодействующем с указанным последовательным портом.

Заключение

Существует множество способов мониторинга трафика на последовательном порту, и выбор инструмента зависит от ваших конкретных потребностей и условий работы. Используйте socat для более глубокого анализа, strace для отслеживания системных вызовов, а также графические интерфейсы, такие как minicom и moserial, для упрощенного взаимодействия. Помните, что каждый из этих подходов имеет свои преимущества, и понимание их работы поможет вам эффективно отладить ваше Java-приложение.

Оцените материал
Добавить комментарий

Капча загружается...