Я пытаюсь диагностировать причину возникновения артефактов \r
при чтении с последовательного терминала.
Следующий код может спровоцировать проблему.Существует встроенное устройство Linux, подключенное к физическому концу кабеля UART
import serial
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=115200,
timeout=5)
ser.reset_input_buffer()
ser.reset_output_buffer()
b_NEW_LINE_WRITTEN = b'\n'
b_alphabet = b'A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Y y Z z'
ser.write(b_alphabet + b_NEW_LINE_WRITTEN)
raw_line = ser.readline()
print(raw_line)
# b'A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q\rq R r S s T t U u V v W w X x Y y Z z\r\n'
На распечатке прочитанные данные имеют \r
вокруг буквы q
.
При запускеэмулятор терминала поверх /dev/ttyUSB0
строка начинает обтекать себя после 80 символов, аналогично этот вопрос .Это перенос строки выглядит как проявление /r
, которое я получаю при непосредственном чтении с примером кода Python.
При подключении к эмулятору терминала (picocom
) эта проблема решается запуском:
shopt -s checkwinsize
resize
после этого нет переносов строк.Я пытаюсь понять, почему это происходит или где (хост, где /dev/tttyUSB0
, что добавляет их или они добавляются встроенным устройством, к которому осуществляется доступ), и как обойти это без необходимости запуска внешних команд.
Следующие кандидаты могут быть причиной поведения:
- настройки драйвера для
/dev/ttyUSB0
на снимке ps - настройки драйвера для
/dev/S0
на целевом встроенном устройстве - оболочка на целевом устройстве
Настройка /dev/ttyUSB0
Попытка изменить /dev/ttyUSB0
в отдельном терминале, пока устройство используетсяСценарий python не показывает никаких изменений.
# Separate terminal on the host
stty -F /dev/ttyUSB0 cols 100
stty -F /dev/ttyUSB0 raw
stty -F /dev/ttyUSB0 -a
speed 115200 baud; rows 80; columns 100; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany
-imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke
-flusho -extproc
#ipython
...
ser.write(b_alphabet + b_NEW_LINE_WRITTEN)
raw_line = ser.readline()
print(raw_line)
# b'A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q\rq R r S s T t U u V v W w X x Y y Z z\r\n'
Настройка /dev/S0
Установка целевого устройства tty также не влияет на существование артефактов.
stty_cmd_set = b'stty cols 200'
ser.write(stty_cmd_set + b_NEW_LINE_WRITTEN)
ser.reset_input_buffer()
ser.reset_output_buffer()
stty_cmd_confirm = b'stty -a'
ser.write(stty_cmd_confirm + b_NEW_LINE_WRITTEN)
# After reading a few lines there is a confirmation that the tty device on the target has indeed been set to 200
print(ser.readline())
b'speed 115200 baud; rows 56; columns 200; line = 0;\r\n'
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.write(b_alphabet + b_NEW_LINE_WRITTEN)
raw_line = ser.readline()
print(raw_line)
# b'A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q\rq R r S s T t U u V v W w X x Y y Z z\r\n'
Например, обходной путь может заключаться в том, чтобы каким-то образом установить фиксированное количество 200 столбцов перед чтением, чтобы последовательный терминал прекратил попытки быть умным.