Удобно работать с виртуальной машиной XPSP3 в VirtualBox’е: когда надо включаешь её, когда не надо – выключаешь, всё очень быстро, и вирусы прочно экранируются. Но вот понадобилось внести изменения в отлаживаемую «виндовую» программу, работающую со старыми добрыми компортами. И тут обнаруживается: не работает компорт виртуальной машины. В ЛОРе нет хорошего ответа. Всё сводится к рекомендации создания новой машины, а это время. Западные пользователи на форумах тоже дают немало пустых советов. А на самом деле всё не так уж и сложно.

Сначала надо установить утилиту настройки аппаратного компорта хост-машины. Называется она setserial, в дистрибутивах Ubuntu её нет, но зато она есть в репозиториях, поэтому воспользуемся командой терминала:

sudo apt-get install setserial

И, конечно, запустим эту утилиту, чтобы посмотреть, присутствует ли на материнской плате, что собой представляет и как настроен аппаратный порт хозяйки (далее в примере исследуем COM1):

sudo setserial -g /dev/ttyS0

Учтите, что ttyS0 соответствует COM1, ttyS1 соответствует COM2 и т.д. согласно терминологии Линукса. Подставьте нужное. После ввода пароля суперпользователя в норме должен быть получен ответ:

/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4

Иначе компорт отсутствует или отключен на уровне BIOS’а хост-машины. Выключенный порт включаем. В случае отсутствия на материнской плате аппаратного компорта придётся поставить «костыль» из дополнительной PCI-платы расширения и добавить модуль его драйвера из прилагаемого к ней диска. Проверено: для Линукса драйверы раюотоспособны, но уточните номер появившегося компорта командой терминала

При необходимости параметры настройки коммуникационного порта можно откорректировать ( как именно – см. терминальной командой man setserial).

Настраиваем проключение виртуального COMn в аппаратный COMn, то бишь в файл ttySn+1. Для этого запускаем VirtualBox, НЕ ЗАПУСКАЯ ВИРТУАЛЬНУЮ МАШИНУ, и настраиваем параметры её компорта, как показано на этом скриншоте:

Здесь важно, чтобы номер порта, номер прерывания и адрес ввода-вывода совпадали бы с теми, которые проиндицировала утилита setserial. Если не совпадают, то утилита setserial поможет перенастроить параметры аппаратного компорта.

Но если вы сейчас попытаетесь запустить виртуальную машину, то с очень большой вероятностью получите ошибку. А всего-то надо сделать ещё две вещи.

Во-первых, вы, хотя и являетесь «главным администратором», не обязательно автоматически являетесь членом группы пользователей виртуальной машины. Удивительно? Но бывает нередко. Впрочем, эта нелепость устраняется легко. Чтобы не заморачиваться с CLI, установите с помощью эмулятора терминала великолепную утилиту gnome-system-tools (она есть в репозиториях) командой

sudo apt-get install gnome-system-tools

Данную утилиту рекомендую для многократного употребления, поэтому скопируйте из папки /usr/share/applications значок «Пользователи и группы» на рабочий стол и запустите эту утилиту из рабочего стола. Откроется окно «Параметры пользователей». Жмите кнопку «Управление группами», в открывшемся окне «Параметры групп» скроллингом отыщите группу vboxusers, выберите её и дважды щёлкните по ней. Откроется окно «Свойства группы vboxusers». Внутри панели «Члены группы» пометьте чекбокс напротив своего имени, отражающего вас, как пользователя системы.

Во вторых, реальному порту следует присвоить права «666», что означает разрешение дуплексного обмена через компорт на уровнях владельца, членов его группы и остальных пользователей. Делается это командой

sudo chmod 666 /dev/ttyS0

Вместо ttyS0 подставьте обозначение нужного аппаратного компорта хост-машины. Вcё, теперь можно смело запускать виртуальную машину, включать привычный «виндовый» гипертерминал и с помощью виртуальной Windows настраивать модемы, управлять программаторами и т.д. Словом, делать всё то, как будто бы вы работали с реальной Windows XP или «семёркой». Успехов!

Личный блог Вадима Кузнецова, RA3XDH

воскресенье, 27 июля 2014 г.

Работа с последовательным портом из консоли Linux

В предыдущем посте было показано как запустить UART на отладочной плате Launchpad для MSP430. Теперь рассмотрим как общаться с платой при помощи средств командной строки Linux. Используется плата с прошивкой из предыдущего поста. Для подробностей — см. под кат

Как известно, все устройства последовательных портов представлены файлами устройств в каталоге /dev.Через эти файлы и происходит общение ОС Linux с внешним устройством на последовательном порту. Чтобы передать что-то на внешнее устройство нужно записать данные в файл устройства, а чтобы считать информацию из устройства — прочитать данные из файла устройства. Это можно делать при помощи команд cat и echo так же как для обычных файлов на диске. Или внутри программы на С при помощи вызовов ioctl(), read() и write() или библиотеки termios.

Физическим последовательным портам RS232, к которым подключались диалапные модемы на старых компьютерах, соответствуют файлы устройств /dev/ttyS*, начиная с /dev/ttyS0. Виртуальным последовательным портам, которые создаются различными конвертерами USB UART соответствуют файлы устройств /dev/ttyUSB* и /dev/ttyACM*. Ядро Linux автоматически разпознаёт подключенное устройство, загружает для него драйвер и создаёт файл устройства. Вручную устанавливать драйвер, как в ОС Windows не требуется. Например, если подключить к USB преобразователь USB UART FT232, то создаётся файл устройства /dev/ttyUSB0, с которым можно работать также как и с обычным последовательным портом. На плате Launcpad находится микросхема TUSB3410, которая тоже представляет собой конвертер USB UART. Если подключить её к USB, то создаётся файл устройства /dev/ttyACM0. Чтобы общаться с платой нужно что-либо писать/читать с этого файла.

Чтобы пользователь мог читать или писать в файл устройства последовательного порта, его нужно добавить в группу dialout. Иначе работать с последовательным портом сможет только администратор root.

Простейшим приложением с графическим интерфейсом, которое работает с последовательным портом, является CuteCOM. Он обычно уже есть в вашем дистрибутиве Linux. Его можно установить из репозиториев. При помощи CuteCOM мы работали с платой в предыдущем посте. Выглядит CuteCOM вот так:

Работать с ним крайне просто. Указываем нужное устройство, если его нет в списке, то его можно впечатать вручную. Затем указываем скорость и параметры и нажимаем OpenDevice. В окне видим данные, которые пришли от устройства. В поле ввода в нижней части можем печать строку символов, которые предаются на устройство. Чтобы передать данный нажимаем Enter и смотрим ответ устройства в окне.

Теперь рассмотрим как работать с COM-портом из командной строки. Для этого служат три команды: stty, cat и echo.

Команда stty устанавливает параметры и скорость COM-порта. Её формат:

stty -F

Чтобы установить параметры для платы Launchpad для соединения на скорости 9600 нужно выполнить:

$ stty 9600 -F /dev/ttyACM0 raw -echo

Параметр raw устанавливает, что данные в компьютер передаются байт за байтом так же как приходят в порт без преобразований. Аппаратное управление потоком отключено. Подробнее о том, что включает и выключает raw — см. man stty. Если не включить raw, то скорее всего ничего работать не будет.

Теперь в той же консоли нужно набрать

$ cat /dev/ttyACM0

И можно смотреть данные, которые приходят от платы. Выход — нажать Ctrl+C.

Теперь нажимаем на плате RESET и видим, что в консоди напечатался текст.

Чтобы передать в плату данные, в другой консоли нужно использовать команду echo и перенаправление вывода в файл устройства. Наберём в другой консоли:

$ echo "1">/dev/ttyACM0

Видим, что на плате загорелся красный светодиод и в первой консоли было выдано сообщение об этом. Чтобы убрать конец строки в передаваемых данных, то нужно использовать запуск echo -n, а чтобы интерпретировать 16-ричные коды — нужно echo -e. Ключи можно комбинировать.

В итоге должно получиться так:

Чтобы увидеть 16-ричные коды данных, приходящих от устройства, нужно использовать команду hexdump:

$ cat /dev/ttyACM0|hexdump -C

Получится вот так:

Чтобы иметь вывод данных от устройство на экран и в текстовый файл нужно использовать tee:

Мне нужно протестировать приложение последовательного порта на Linux, однако моя тестовая машина имеет только один последовательный порт.

есть ли способ, чтобы добавить виртуальный последовательный порт в Linux и тестировать приложение, эмулируя устройство через или скрипт?

примечание: Я не могу переназначить порт, он жестко закодирован на ttys2, и мне нужно проверить приложение, как оно написано.

8 ответов

для этого можно использовать pty ("псевдо-телетайп", где последовательный порт является "реальным телетайпом"). С одного конца откройте /dev/ptyp5 , а затем прикрепите программы /dev/ttyp5 ; ttyp5 будет действовать как последовательный порт, но будет отправлять/получать все, что он делает через /dev/ptyp5.

Если вам действительно нужно поговорить с файлом под названием /dev/ttys2 , тогда просто переместите свой старый /dev/ttys2 из Пути и сделать символическую ссылку из ptyp5 to ttys2 .

конечно, вы можете использовать ряд других чем ptyp5 . Возможно, выберите один с большим числом, чтобы избежать дублирования, так как все ваши терминалы входа также будут использовать ptys.

дополняя ответ @slonik.

вы можете протестировать socat для создания виртуального последовательного порта, выполнив следующую процедуру (протестировано на Ubuntu 12.04):

откройте терминал (назовем его терминалом 0) и выполните его:

код выше возвращает:

откройте другой терминал и напишите (Терминал 1):

имя порта этой команды можно изменить согласно к компьютеру. это зависит от предыдущего вывода.

вы должны использовать номер, доступный на выделенной области.

откройте другой терминал и напишите (Терминал 2):

теперь вернемся к терминалу 1, и вы увидите строку "Test".

используйте socat для этого:

существует также tty0tty http://sourceforge.net/projects/tty0tty/ который является реальным эмулятором нулевого модема для linux.

Это простой модуль ядра — небольшой исходный файл. Я не знаю, почему он только опустил большие пальцы на sourceforge, но он хорошо работает для меня. Самое лучшее в этом — это эмуляция аппаратных контактов (RTC/CTS DSR / DTR). Он даже реализует команды TIOCMGET / TIOCMSET и TIOCMIWAIT iotcl!

на недавнем ядре вы можете получить ошибка компиляции. Это легко исправить. Просто вставьте несколько строк в верхней части модуля / tty0tty.C Источник (после включения):

когда модуль загружен, он создает 4 пары последовательных портов. Приборы /dev /tnt0 к/dev / tnt7 где tnt0 соединено к tnt1, tnt2 соединено к tnt3, etc. Вам может понадобиться исправить права доступа к файлам, чтобы иметь возможность использовать устройства.

Я думаю, что я немного поспешила с моим энтузиазмом. А водитель выглядит многообещающе, он кажется нестабильным. Я не знаю точно, но я думаю, что он разбил машину в офисе, над которым я работал из дома. Я не могу проверить, пока не вернусь в офис в понедельник.

второе, что TIOCMIWAIT не работает. Код, похоже, скопирован из некоторого примера кода" tiny tty". Обработка TIOCMIWAIT кажется на месте, но она никогда не просыпается, потому что соответствующий вызов wake_up_interruptible() недостающий.

вчера и сегодня я переписывал драйвер. Было много проблем, но теперь это хорошо работает для меня. По-прежнему отсутствует код для аппаратного управления потоком, управляемого драйвером, но мне это не нужно, потому что я сам буду управлять контактами TIOCMGET/TIOCMSET / TIOCMIWAIT из кода пользовательского режима.

Если кто-то заинтересован в моей версии кода, отправьте мне сообщение, и я отправлю его вам.

вы можете посмотреть Тиббо VSPDL для создания виртуального последовательного порта linux с помощью драйвера ядра — он кажется довольно новым и доступен для загрузки прямо сейчас (бета-версия). Не уверен в лицензии на данный момент, или они хотят, чтобы сделать его доступным коммерчески только в будущем.

есть и другие коммерческие альтернативы, такие как http://www.ttyredirector.com/.

В Open Source,Remserial (GPL) также может делать то, что вы хотите, используя UNIX PTY. Он передает последовательные данные в "сырой форме" в сетевой сокет; STTY-подобная настройка параметров терминала должна быть выполнена при создании порта, изменение их позже, как описано в RFC 2217, похоже, не поддерживается. Вы должны иметь возможность запускать два экземпляра remserial для создания виртуального nullmodem, такого как com0com, за исключением того, что вам нужно заранее настроить скорость порта и т. д.

Socat (также GPL) похож на расширенный вариант Remserial со многими другими параметрами, включая метод" PTY " для перенаправления PTY на что-то еще, что может быть другим экземпляром Socat. Для Unit tets socat, вероятно, лучше, чем remserial, потому что вы можете напрямую использовать файлы cat в PTY. Вижу PTY пример на странице. А патч существует в разделе "contrib" для обеспечения поддержки RFC2217 для согласования настроек последовательной линии.

используя ссылки, опубликованные в предыдущих ответах, я закодировал небольшой пример на C++, используя виртуальный последовательный порт. Я ввел код в GitHub:https://github.com/cymait/virtual-serial-port-example .

код довольно понятен. Во-первых, вы создаете главный процесс, запустив его ./ главный мастер и он напечатает к stderr прибор использует. После этого вы призываете ./ главное ведомое устройство, где устройство-это устройство, напечатанное в первом команда.

и это все. Между этими двумя процессами существует двунаправленная связь.

используя этот пример, вы можете проверить приложение, отправив все виды данных и посмотреть, правильно ли оно работает.

кроме того, вы всегда можете символически связать устройство, поэтому вам не нужно повторно компилировать приложение, которое вы тестируете.

вы могли бы использовать адаптер USB->RS232? У меня есть несколько, и они просто используют драйвер FTDI. Затем вы сможете переименовать /dev /ttyUSB0 (или все, что будет создано) как/dev / ttyS2 .

Я могу придумать три варианта:

реализовать RFC 2217

RFC 2217 охватывает com-порт по стандарту TCP/IP, который позволяет клиенту в одной системе эмулировать последовательный порт для локальных программ, при этом прозрачно отправляя и получая данные и сигналы управления на сервер в другой системе, которая фактически имеет последовательный порт. Вот обзор.

Что бы вы сделали, это найти или реализовать драйвер com-порта клиента это реализовало бы клиентскую часть системы на вашем ПК-казалось бы, настоящий последовательный порт, но на самом деле все на сервер. Вы можете получить этот драйвер бесплатно от Digi, Lantronix и т. д. В поддержку своих реальных автономных серверов последовательных портов.

затем вы реализуете серверную часть соединения локально в другой программе-позволяя клиенту подключаться и выдавать данные и команды управления по мере необходимости.

Это, наверное, нетривиально, но RFC существует, и вы можете найти проект с открытым исходным кодом, который реализует одну или обе стороны соединения.

измените драйвер последовательного порта linux

альтернативно, источник драйвера последовательного порта для Linux легко доступен. Возьмите это, выпотрошите аппаратные элементы управления и попросите, чтобы один драйвер запускал два порта /dev/ttySx, как простой цикл. Затем подключите вашу реальную программу к ttyS2 и ваш симулятор к другому ttySx.

используйте два USB последовательных кабеля в петле

но что проще всего сделать прямо сейчас? Потратьте $ 40 на два USB-устройства с последовательным портом, соедините их вместе (нулевой модем) и фактически имейте два реальных последовательных порта — один для тестируемой программы, один для вашего симулятора.