Тест петли / дуплекс последовательного порта, в Bash или C? (процесс замены)
У меня есть последовательное устройство, настроенное как loopback (то есть оно будет просто отображать любой полученный символ), и я хотел бы измерить эффективную скорость передачи. Для этого я надеялся использоватьtime
, как в
time bash -c '...'
где '...
«Это была бы какая-то команда, которую я мог бы выполнить.
Теперь, первая проблема заключается в том, что я хочу использовать устройство на скорости 2000000 бит / с, поэтому я не могу использоватьttylog или жеэкран (похоже, что они оба работают со скоростью до 115200 бит / с). Тем не менее, работа с/dev/ttyUSB0
как файл (используя перенаправление файла иcat
) вроде нормально работает
# initialize serial port
stty 2000000 -ixon icanon </dev/ttyUSB0
# check settings
stty -a -F /dev/ttyUSB0
# in one terminal - read from serial port
while (true) do cat -A /dev/ttyUSB0 ; done
# in other terminal - write to serial port
echo "1234567890" > /dev/ttyUSB0
# back to first terminal, I now have:
# $ while (true) do cat -A /dev/ttyUSB0 ; done
# 1234567890$
# ...
Теперь я хотел бы сделать что-то подобное - я бы хотелcat
файл к последовательному порту, и иметь последовательный порт для чтения обратно - но из одной команды терминала (так что я мог бы использовать его в качестве аргумента дляtime
).
Я подумал, что мог бы использовать подстановку процесса Bash, чтобы части «записи» и «чтения» перешли, вроде как, в «параллель» - если я попробую это с именованными каналами, это сработает:
# mkfifo my.pipe # same as below:
$ mknod my.pipe p
$ comm <(echo -e "test\ntest\ntest\n" > my.pipe) <(cat my.pipe)
test
test
test
comm: file 2 is not in sorted order
Там я не пользуюсьcomm
для любой другой цели, чем (вроде) объединить два процесса в одну команду (я думаю, я мог бы так же хорошо использоватьecho
вместо).
К сожалению, этот трюк не работает с последовательным портом, потому что, когда я пробую его, я иногда получаю:
$ comm <(echo "1234567890" > /dev/ttyUSB0) <(while (true) do cat -A /dev/ttyUSB0 ; done)
cat: /dev/ttyUSB0: Invalid argument
... однако, обычно я просто не получаю никакого вывода вообще. Это говорит мне, что: либо нет контроля над тем, какой процесс запускается первым, и такcat
может начать чтение до того, как порт будет готов (однако в первом примере выше это не является проблемой); или в Linux / Bash, вы не можете одновременно читать и записывать в последовательный порт, и поэтомуInvalid argument
"произойдет в те моменты, когда и чтение, и запись, кажется, происходят одновременно.
Итак, мои вопросы:
Есть ли способ сделать что-то подобное (cat
файл на последовательный порт, настроенный как loopback; прочитайте его и посмотрите, сколько времени это займет) только в Bash, не прибегая к написанию специальной программы на C?Если мне нужна выделенная программа на C, какие-нибудь исходные примеры в сети, которые я мог бы использовать?Большое спасибо за любые ответы,
Ура!
РЕДАКТИРОВАТЬ: я знаю, чтоwhile
цикл, написанный выше, не завершается; эта командная строка была для предварительного тестирования, и я прерываю ее, используя Ctrl-C. (Я мог бы в принципе прервать его чем-то вродеtimeout -9 0.1 bash -c 'while (true) do echo AA ; done'
, но это победило бы цельtime
, затем :) )
Причина того, чтоwhile
есть ли, в настоящее время, чтение черезcat
с устройства выходит сразу; иногда яиметь настроить устройство так, чтобы приcat
выдается, он фактически блокирует и ждет поступающие данные; но я пока не могу понять, что происходит (и частично поэтому я ищу способ тестирования из командной строки).
В случае, если я не использовалwhile
Представляю, я бы использовал что-то вроде:
time bash -c 'comm <(echo "1234567890" > /dev/ttyUSB0) <(cat -A /dev/ttyUSB0)'
... однако для того, чтобы это работало, вроде как, предполагается, чтоcat -A /dev/ttyUSB0
начинается сначала и блокирует; тогдаecho
пишет в последовательный порт (и выходит); а потомcat -A
выводит все, что читает из последовательного порта, а затем завершает работу. (И я не совсем уверен, может ли последовательный порт вообще так себя вести, и неcat
может быть сделано, чтобы заблокировать и выйти произвольно, как это).
Точный метод действительно не имеет значения; если это вообще возможно, я бы просто хотел избежать написания моей собственной C-программы для такого рода тестирования, поэтому мой основной интерес заключается в том, возможно ли как-нибудь выполнить такой «полнодуплексный тест» с использованием базового Bash / Linux (т.е.coreutils
); (и если нет, если есть готовый код, который я могу использовать для чего-то вроде этого).
РЕДАКТИРОВАТЬ 2: Также возможно актуально:
Параллельные процессы в Bash - Форумы Ubuntu