- Вопрос или проблема
- Это то, что я в конечном итоге выбрал
- Ответ или решение
- Как контролировать трафик последовательного порта: подробное руководство
- 1. Использование socat для мониторинга последовательного порта
- 2. Применение strace для отслеживания системных вызовов
- 3. Простые инструменты для мониторинга
- 4. Альтернативные инструменты
- 5. Практический подход к отладке
- Заключение
Вопрос или проблема
Есть ли какой-либо инструмент для мониторинга порта, чтобы отслеживать пакеты, записываемые на порт? Я особенно хочу проверить, работает ли моя программа, написанная на Java, поэтому мне нужен какой-то инструмент, чтобы увидеть, пишет ли моё небольшое приложение сообщения в порт. Как мне это сделать?
socat — это инструмент для подключения (практически) всего к (практически) всему, и tee может дублировать потоки. В вашем случае вы можете подключить свой последовательный порт /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]'
И это работает примерно так:
- Первая команда socat устанавливает двунаправленный канал между первым адресом (
/dev/ttyUSB0
) и вторым (командаSYSTEM
). - Теперь внутри команды
SYSTEM
tee дублирует свой stdin (т.е. вывод/dev/ttyUSB0
) как в[READ-ONLY PTY]
, так и в свой собственный stdout, который мы затем передаём в[READ-WRITE PTY]
. [READ-ONLY PTY]
создаётся с помощью второй команды socat, где первый адрес – это-
(сокращение для типа адресаSTDIO
в socat), а второй – новое PTY. Мы также следим за тем, чтобы закрыть stdout этой 2-й команды socat с помощью>%-
; это делает его только для чтения.- По какой-то причине, которую я не понимаю, если stdout 2-й socat не закрыт, tee, похоже, включает вывод из подстановки процесса в свой собственный вывод. Я не уверен, почему tee вообще читает свои аргументы.
- Наконец,
[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-приложение.