![Неожиданные результаты тестирования последовательной обратной связи с использованием echo и cat](https://rvso.com/image/23962/%D0%9D%D0%B5%D0%BE%D0%B6%D0%B8%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5%20%D1%80%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D1%8B%20%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9%20%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B9%20%D1%81%D0%B2%D1%8F%D0%B7%D0%B8%20%D1%81%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC%20echo%20%D0%B8%20cat.png)
Итак, у меня есть стандартный последовательный порт RS232, который закольцован сам с собой, просто проложив провод от Tx к Rx. Я тестирую обратную связь, запустив echo
и cat
в двух отдельных терминалах:
cat /dev/ttyS1
echo "hi" > /dev/ttyS1
У меня проблема с выводом. Я ожидал увидеть один "hi" на терминале, запущенном cat, но вместо этого я получаю это:
hi
[2 newlines]
hi
[4 newlines]
hi
[8 newlines]
hi
[16 newlines]
hi
[32 newlines]
hi
...и так далее, пока я ctrlне + c cat
.
После прерывания cat, если я запущу его снова, он не выведет «hi», пока я не запущу echo во второй раз.
Это нормально? Есть идеи, почему я вижу такое поведение?
Редактировать: Под новой строкой я подразумеваю ASCII 0x0A
. В этом выводе нет возвратов каретки.
решение1
Благодаря второму комментарию Брюса я смог самостоятельно разобраться в проблеме.
После запуска stty -a -F /dev/ttyS1
я обнаружил 3 варианта, которые могли способствовать возникновению проблемы: «echo», «onlcr» и «icrnl».
Поскольку этот последовательный порт замкнут сам на себя, вот что произошло после запуска echo "hi" > /dev/ttyS1
:
- По умолчанию команда
echo
добавляет новую строку в конец сообщения, поэтому «hi» + LF отправляется на /dev/ttyS1 - Поскольку было установлено «onlcr», последовательное устройство преобразовало LF в CRLF, поэтому физическое сообщение, отправленное по линии Tx, было «hi» + CRLF
- Поскольку был установлен "icrnl", физическое сообщение, полученное на линии Rx, преобразовало CR в LF. Таким образом, сообщение, выведенное 'cat', было "hi" + LFLF.
- Поскольку было установлено «эхо», сообщение, полученное на линии Rx («hi» + LFLF), затем было отправлено обратно на линию Tx.
- Из-за onlcr «hi» + LFLF превратилось в «hi» + CRLFCRLF.
- Из-за icrnl "hi" + CRLFCRLF превратилось в "hi" + LFLFLFLF
- Из-за эха, "привет" + LFLFLFLF затем был отправлен на передачу
И так далее...
Чтобы решить эту проблему, я выполнил следующую команду:
stty -F /dev/ttyS1 -echo -onlcr
Отключение "echo" предотвращает бесконечный цикл сообщений, а отключение "onlcr" не позволяет последовательному устройству преобразовывать LF в CRLF на выходе. Теперь cat
получает один "hi" (с одним символом новой строки!) каждый раз, когда я запускаю echo
.
CR = возврат каретки (ASCII 0x0D); LF = перевод строки или новая строка (ASCII 0x0A)
решение2
У меня была похожая проблема с объединением файлов в последовательный tty для тестирования. В дополнение к принятому ответу:
Если вы тестируете последовательный вывод, делая что-то вроде: cat somefile.txt > /dev/ttyS0
, то он будет содержать большое количество неожиданных байтовых данных, если вы тестируете точные байтовые значения.
При stty
выполнении простого действия stty raw -F /dev/ttyS0
терминал не сможет вставлять/заменять символы (например, [...] 0x0A [...]
-> [...] 0x0D 0x0A [...]
). raw
Флаг изменяет режимы терминала, поэтому обработка ввода и вывода не выполняется.