Вопрос

Мне нужно протестировать приложение с последовательным портом в 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-устройства с последовательным портом, соедините их вместе (нуль-модем) и фактически получите два реальных последовательных порта — один для программы, которую вы тестируете, другой для вашего симулятора.

-Адам

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top