Сетап:
- Удалённое устройство, подключенное к серверу на Linux
- Управление через COM порт
- Управление тулом под Windows
- Есть SSH доступ
- Само устройство успешно удалённо программируется и отлаживается по JTAG
Нужно:
- Запустить тул локально под Virtual Box (локальная машина тоже Linux)
- Пробросить удалённый последовательный порт локально
- Пробросить его в Virtual Box
Поиск в интернете даёт сходу два результата:
Оба пакета имеются в наличии в Manjaro/ArchLinux и поставить просто:
pacman -S socat ser2net
socat
, к слову, уже был поставлен как зависимость kwallet-pam
.
ser2net
реализует RFC2217.
Предподготовка
Будем пытаться максимально делать всё от обычного пользователя (кроме, пожалуй, установки пакетов).
Создадим каталог $HOME/dev
для наших устройств:
mkdir -p $HOME/dev
Попытка номер раз: только socat
В его man’е есть заманчивая строчка:
socat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \
EXEC:"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"
Пробуем (эксперимент показываю на localhost, сейчас удалёнка вне доступа, но смысл тот же, просто где-то придётся пробросить порты через тот же SSH):
socat PTY,link=$HOME/dev/serial-local,rawer,wait-slave EXEC:"ssh localhost socat - /dev/ttyUSB0,nonblock,rawer"
А далее picocom
:
$ picocom -b 115200 ~/dev/serial-local
picocom v3.1
port is : /home/hatred/dev/serial-local
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
FATAL: read zero bytes from port
term_exitfunc: reset failed for dev UNKNOWN: Input/output error
При этом со стороны socat
:
2023/12/05 11:00:37 socat[1555557] E tcgetattr(7, 0x56489e9255a0): Inappropriate ioctl for device
Это фиаско. Но двигаемся дальше.
Попытка номер два: ser2net и socat
Со стороны “сервера” пробуем запустить ser2net
, а уже локально создать “файл устройства” через socat
.
Сервер:
ser2net -C "7000:telnet:0:/dev/ttyUSB1:remctl" -d -u
Локально (если нужно, пробрасываем порт через ssh):
socat PTY,link=$HOME/dev/serial-local,rawer TCP:localhost:7000
Локально, picocom
:
$ picocom -b 115200 ~/dev/serial-local
picocom v3.1
port is : /home/hatred/dev/serial-local
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
weeeerrrrrttttyyyyqqqqaaassszzxxcvfdsfdsfdsrwrew
со стороны UART Rx и Tx соединены, поэтому наблюдаем Echo.
Это успех!
UPD: успех, но не полный. Петля на Rx-Tx скрыла тот факт, что не было настройки Boudrate. Если бодрейт сильно отличается, то может посыпать мусор и параметр remctl
тут не сильно помогает. Если по простому: то в самом конце цепочки, на уровне picocom может уже не сработать установка baudrate. Нужно править или на уровне socat или команды ser2net. Самое простое, изменить команду ser2net так:
ser2net -C "7000:telnet:0:/dev/ttyUSB1:921600 remctl" -d -u
И однострочник, который пробросит с хоста и порты сразу и запустит команду:
ssh -L '*:7000:localhost:7000' zcu208 'ser2net -C "7000:telnet:0:/dev/ttyUSB1:921600 remctl" -d -u'
А теперь горбатый VirtualBox
Идём в настройки виртуальной машины на вкладку “Serial Ports” и включаем, для примера, COM1.
И, внезапно, обнаруживаем в параметре “Port Mode:” режим “TCP”… А ну ка, указываем там “localhost:7000” (именно на этом порту у нас уже висит ser2net
из предыдущего пункта) и загружаемся.
В Windows в диспетчере видим единственный COM1 и подключаемся к нему через Putty и наблюдаем echo.
Снова успех! Даже запуска socat
не нужно. Но успех частичный, читаем дальше.
Есть, правда, нюанс: до запуска виртуалки к ser2net
не должно быть никакого подключения. Иначе порт появится, а работать не будет.
Второй нюанс: не работают “нестандартные” Baud Rate. К примеру, я не смог поставить 921600. Но они же работают в связке socat+picocom.
Если настраивать через PIPE, то результат ровно такой же. Настройка через PIPE
- Сначала запускаем
socat
:socat UNIX-LISTEN:$HOME/dev/serial-pipe TCP:localhost:7000
- В настройках порта указываем:
- “Port Mode:” → “Host Pipe”
- “Path/Address:” → “~/dev/serial-pipe”
- лучше указать полный путь, который обслуживает socat.
Сдаётся мне, что это особенности стандартного драйвера для стандартных последовательных портов (COM1-4). Поэтому, идём дальше.
Убираем промежуточное звено
На Windows вполне можно себе использовать RFC2217. Поэтому попытаемся создать подключение к ser2net
непосредственно, миную функционал Virtual Box.
Для начала запускаем Telnet или Putty, выбираем протокол telnet, устанавливаем хост в адрес на котором крутится ser2net
и соответствующий порт. Смотрим, что работает. Если не работает - разбираемся с сетью.
Дальше скачиваем необходимые пакеты проекта Null-modem emulator:
-
com2com
- лучше версию 2.2.2.0 дабы не иметь проблем с подписью на новых Windows
- или отключаем проверку подписи, либо курим DSEO
- я скачивал и пробовал (Windows 10 64bit) com0com-2.2.2.0-x64-fre-signed.zip
- hub2com
Первый распаковываем и устанавливаем. После чего запускаем от имени Администратора конфигуратор setupc.exe
и вводим туда:
install PortName=COM19 PortName=COM20
что создаст нам пару виртуальных портов и роутинг между ними. В приложении нужно будет использовать порт COM20, а для сети - COM19. Можно добавить параметр EmuBR=yes
к COM19 для эмуляции скорости, но у меня всё заработало без него.
Далее распаковываем hub4com
, там никаких установщиков нет. И запускаем:
.\com2tcp-rfc2217 \\.\COM19 192.168.0.104 7000
здесь:
- COM19 - первый из пары виртуальных адресов
- 192.168.0.104 - адрес, где крутится
ser2net
на Linux - 7000 - соответственно порт, который слушает
ser2net
В Putty пробуем открыть COM20 с нестандартным рейтом, например - 921600. И вот тут оно начинает работать.
Терминал с запущенным com2tcp-rfc2217.bat
закрывать не нужно, иначе связь разорвётся.
Теперь точно успех!