Виртуальный последовательный порт для Linux
-
09-06-2019 - |
Вопрос
Мне нужно протестировать приложение с последовательным портом в Linux, однако моя тестовая машина имеет только один последовательный порт.
Есть ли способ добавить виртуальный последовательный порт в Linux и протестировать мое приложение, эмулируя устройство через оболочку или сценарий?
Примечание:Я не могу переназначить порт, он жестко запрограммирован на ttys2, и мне нужно протестировать приложение в том виде, в котором оно написано.
Решение
Для этого вы можете использовать pty («псевдотелетайп», где последовательный порт — это «настоящий телетайп»).С одного конца открыть /dev/ptyp5
, а затем прикрепите свою программу к /dev/ttyp5
; ttyp5
будет действовать как последовательный порт, но будет отправлять/получать все, что он делает, через /dev/ptyp5.
Если вам действительно нужно это для общения с файлом с именем /dev/ttys2
, затем просто переместите свой старый /dev/ttys2
в сторону и создайте символическую ссылку из ptyp5
к ttys2
.
Конечно, вы можете использовать любое число, отличное от ptyp5
.Возможно, выберите один с большим номером, чтобы избежать дублирования, поскольку все ваши терминалы входа также будут использовать ptys.
В Википедии есть дополнительная информация о ptys: http://en.wikipedia.org/wiki/Pseudo_terminal
Другие советы
Дополняя ответ @slonik.
Вы можете протестировать socat для создания виртуального последовательного порта, выполнив следующую процедуру (проверено на Ubuntu 12.04):
Откройте терминал (назовем его Терминал 0) и выполните его:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
Код выше возвращает:
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]
Откройте другой терминал и напишите (Терминал 1):
cat < /dev/pts/2
Имя порта этой команды можно изменить в зависимости от компьютера.это зависит от предыдущего вывода.
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs
вам следует использовать номер, доступный в выделенной области.
Откройте другой терминал и напишите (Терминал 2):
echo "Test" > /dev/pts/3
Теперь вернитесь к Терминалу 1 и вы увидите строку «Тест».
Используйте socat для этого:
Например:
socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11
Еще есть tty0tty http://sourceforge.net/projects/tty0tty/ это настоящий эмулятор нуль-модема для Linux.
Это простой модуль ядра — небольшой исходный файл.Я не знаю, почему SourceForge получил только отрицательные отзывы, но у меня он работает хорошо.Самое приятное то, что он также эмулирует аппаратные контакты (RTC/CTS DSR/DTR).Он даже реализует команды iotcl TIOCMGET/TIOCMSET и TIOCMIWAIT!
В последнем ядре вы можете получить ошибки компиляции.Это легко исправить.Просто вставьте несколько строк в начало исходного кода модуля/tty0tty.c (после включения):
#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif
Когда модуль загружается, он создает 4 пары последовательных портов.Это устройства от /dev/tnt0 до /dev/tnt7, где tnt0 подключен к tnt1, tnt2 подключен к tnt3 и т. д.Возможно, вам придется исправить права доступа к файлам, чтобы иметь возможность использовать устройства.
редактировать:
Наверное, я немного поспешил с энтузиазмом.Хотя драйвер выглядит многообещающе, он кажется нестабильным.Я не знаю наверняка, но думаю, что это сломало машину в офисе, над которой я работал дома.Я не смогу проверить, пока не вернусь в офис в понедельник.
Во-вторых, TIOCMIWAIT не работает.Кажется, что код скопирован из какого-то примера кода «крошечного tty».Обработка TIOCMIWAIT кажется на месте, но она никогда не просыпается, поскольку соответствующий вызов Wake_up_interruptible() отсутствует.
редактировать:
Авария в офисе действительно произошла по вине водителя.Отсутствовала инициализация, а совершенно непроверенный код TIOCMIWAIT вызвал сбой машины.
Вчера и сегодня потратил на переписывание драйвера.Было много проблем, но теперь у меня все работает хорошо.Все еще отсутствует код для аппаратного управления потоком данных, управляемого драйвером, но он мне не нужен, поскольку я буду сам управлять выводами, используя TIOCMGET/TIOCMSET/TIOCMIWAIT из кода пользовательского режима.
Если кого-то заинтересует моя версия кода, отправьте мне сообщение, и я пришлю его вам.
Возможно, вы захотите посмотреть Тиббо ВСПДЛ для создания виртуального последовательного порта Linux с использованием драйвера ядра — он кажется довольно новым и доступен для загрузки прямо сейчас (бета-версия).На данный момент не уверен насчет лицензии и хотят ли они сделать ее коммерчески доступной только в будущем.
Существуют и другие коммерческие альтернативы, такие как http://www.ttyredirector.com/.
В открытом исходном коде ресериал (GPL) также может делать то, что вы хотите, используя Unix PTY.Он передает последовательные данные в «сыром виде» в сетевой сокет;Настройка параметров терминала в стиле STTY должна быть выполнена при создании порта, изменение их позже, как описано в RFC 2217, похоже, не поддерживается.У вас должна быть возможность запустить два экземпляра remserial для создания виртуального нуль-модема, такого как com0com, за исключением того, что вам нужно будет заранее настроить скорость порта и т. д.
Сокат (также GPL) похож на расширенный вариант Remserial со многими другими опциями, включая метод «PTY» для перенаправления PTY на что-то другое, что может быть другим экземпляром Socat.Для Unit-тетов socat, вероятно, предпочтительнее, чем remserial, поскольку вы можете напрямую помещать файлы в PTY.См. Пример PTY на странице руководства.А патч существует в разделе «contrib», чтобы обеспечить поддержку RFC2217 для согласования настроек последовательной линии.
Используя ссылки, опубликованные в предыдущих ответах, я написал небольшой пример на C++ с использованием виртуального последовательного порта.Я отправил код на GitHub: https://github.com/cymait/virtual-serial-port-example .
Код довольно понятен.Сначала вы создаете главный процесс, запустив ./main master, и он будет печатать в stderr, который использует устройство.После этого вы вызываете ./main подчиненное устройство, где устройство — это устройство, указанное в первой команде.
Вот и все.У вас есть двунаправленная связь между двумя процессами.
Используя этот пример, вы можете протестировать приложение, отправив все виды данных, и посмотреть, правильно ли оно работает.
Кроме того, вы всегда можете создать символическую ссылку на устройство, поэтому вам не придется перекомпилировать тестируемое приложение.
Можно ли использовать переходник USB->RS232?У меня их несколько, и они просто используют драйвер FTDI.Затем вы сможете переименовать /dev/ttyUSB0 (или что-то еще, что будет создано) в /dev/ttyS2 .
Я могу придумать три варианта:
Внедрить RFC 2217
РФК 2217 соответствует стандарту TCP/IP, который позволяет клиенту в одной системе эмулировать последовательный порт для локальных программ, одновременно прозрачно отправляя и получая данные и управляющие сигналы на сервер в другой системе, которая фактически имеет последовательный порт.Вот общий обзор.
Что вам нужно сделать, так это найти или внедрить драйвер клиентского COM-порта, который будет реализовывать клиентскую часть системы на вашем ПК - выглядит как настоящий последовательный порт, но на самом деле передает все на сервер.Возможно, вы сможете получить этот драйвер бесплатно от Digi, Lantronix и т. д. для поддержки их реальных автономных серверов последовательного порта.
Затем вы реализуете серверную часть соединения локально в другой программе, позволяя клиенту подключаться и выдавать данные и команды управления по мере необходимости.
Вероятно, это нетривиально, но RFC существует, и вы, возможно, сможете найти проект с открытым исходным кодом, реализующий одну или обе стороны соединения.
Измените драйвер последовательного порта Linux.
Альтернативно, исходный код драйвера последовательного порта для Linux легко доступен.Возьмите это, выпотрошите аппаратные элементы управления и заставьте этот драйвер запускать два порта /dev/ttySx в качестве простой обратной связи.Затем подключите вашу реальную программу к ttyS2, а симулятор — к другому ttySx.
Используйте два кабеля USB<-->Serial в шлейфе.
Но что проще всего сделать прямо сейчас?Потратьте 40 долларов на два USB-устройства с последовательным портом, соедините их вместе (нуль-модем) и фактически получите два реальных последовательных порта — один для программы, которую вы тестируете, другой для вашего симулятора.
-Адам