Работа с COM-портом (RS-232) в Linux
Урок посвящен интерфейсу RS-232, который в простонародье называют COM-порт. Мы разберемся как он представлен в Linux, какой у него интерфейс, научимся его конфигурировать, а также узнаем, что написание программы для коммуникации через COM-порт в Linux не представляет сложности.
Разговор o коммуникации через COM-порт в Linux следует начать с того, что заметить, что каждому COM-порту в операционной системе соответствует файл устройства телетайп или tty. Он находится в каталоге dev и имеет имя /dev/ttyS и номер. Если посмотреть на мой каталог, то мы увидим следующее, что у меня таких файлов очень много [0:55]. Но по факту, в моем компьютере есть один физический COM-порт. Давайте попробуем его найти. Сделать это можно с помощью команды dmesg, которая выводит сообщения с момента инициализации системы. Если набрать
$dmeg | grep «ttyS»
то мы увидим, что, в действительности , у меня только один файл ttyS4 связанный с конкретным COM-портом, у которого есть некоторый диапазон ввода/вывода, номер прерывания, и который сейчас настроен на скорость обмена 150200 бит в секунду (или бод).
Для того, чтобы сконфигурировать мой COM-порт по умолчанию в Linux можно воспользоваться программой mincom, запускать её нужно от суперпользователя, либо добавить текущего пользователя в группу dialout. Запустим
$sudo minicom -s
Ключ -s – обозначает конфигурацию (setup),
Здесь мы видим следующее [2:24]. Есть параметры последовательного порта, важно прописать правильно файл, то есть указать тот файл, который у вас в системе связан с физическим COM-портом, Второй важный момент – это настройка параметров обмена (ключ Е). Дело в том, что корректный обмен данными по последовательному соединению возможен только тогда, когда обе стороны имеют один и тот же набор параметров. В этом окне можно набор этих параметров менять [3:08]. Мы видим, что у нас задана скорость 8 бит, нет контроля четности, и один стоповый бит. Именно здесь можно это все увидеть и настроить так, как требуется или, как требует ваше устройство.
Сохраняем конфигурацию по умолчанию. Дальше будем взаимодействовать — сначала с помощью команды терминала, чтобы проверить, как вручную это работает; а потом напишем небольшую программу, которая будет слать данные в COM-порт. Выйти из Mincom можно набрав ctrl-A-X.
Для того чтобы проверить, как работает COM-порт можно воспользоваться программой miniterm [4:03]. Я создал виртуальную машину с обычным linux, у неё указал, что в наличии имеется один COM-порт (это COM1), по умолчанию назначились линии обработки запросов прерывания. Я ассоциировал этот COM-порт с файлом на моей host-машине. С этого файла мы будем читать данные записанные в порт.
Итак, мы видим, что в левой части экрана у нас есть логин на виртуальную машину [4:46]. Давайте проверим с помощью minicom -s, как настроены коммуникации. Проверим, что /dev/ttyS0 – это действительно правильный физический порт – да, это именно так. Теперь мы можем вызвать команду
$sudo miniterm
она говорит, что есть следующие доступные порты, и просит ввести, через какой порт работать. Далее я попадаю терминал, связанный с COM-портом, где могу набирать текст. Набирая команды, я вижу «эхо» в моем файле справа. Обратите внимание, что я пишу в левом окне, а на экране надпись мы видим в правом. В левом окошке – виртуальная машина, на которой настроен порт. В правом – тот лог, который мы видим в файле ассоциированном с этим COM-портом на host-машине.
Создадим какой-нибудь каталог, в котором будем разрабатывать приложение. Как это ни странно, приложение будет выглядеть очень просто, потому что все действия, которые мы делаем с COM-портом в linux, это действия с файлами с использованием тех же самых файловых операций. Нам потребуется stdio.h, unistd.h, чтобы получить доступ – функциям open/read/write, fcntl.h, чтобы иметь возможность использовать файловые флажки. Открываем файловый дескриптор, COM-порт, имя, и флаги из COM-порта. Проверим, что файловый дескриптор у нас открылся, то есть если порт меньше или равен 0, то есть какая-то ошибка, оповестим об этом пользователя и вернем управление. В противном случае, можно писать в этот файловый дескриптор. write принимает файловый дескриптор, указатель на буфер, размер. Дальше мы закрываем файловый дескриптор и возвращаем управление. Приложение готово.
Теперь давайте попробуем запустить то, что у нас вышло, вернее, скомпилировать и запустить [10:40]. При запуске приложения произошла ошибка, но она вызвана понятными причинами, потому что пользователь должен был быть включен группу dialout [11:03], или нам надо запускать приложение от суперпользователя. Сделаем это. И сразу видим, что в нашем окошке появилась запись «hello world». Можно повторить и увидеть, что все работает корректно.
Точно таким же образом можно осуществлять чтение из COM-порта, то есть использовать не функцию write, а функцию read.
Источник
Виртуальный последовательный порт для Linux
Мне нужно протестировать приложение последовательного порта в Linux, однако у моего тестового компьютера только один последовательный порт.
Есть ли способ добавить виртуальный последовательный порт в Linux и протестировать мое приложение, эмулируя устройство через оболочку или script?
Примечание. Я не могу переназначить порт, он жестко закодирован на ttys2, и мне нужно протестировать приложение, как оно написано.
Вы можете использовать pty ( “псевдотелевизор”, где для этого используется последовательный порт “настоящий телетайп” ). С одного конца откройте /dev/ptyp5 , а затем добавьте свою программу в /dev/ttyp5 ; ttyp5 будет действовать как последовательный порт, но будет отправлять/получать все, что он делает через /dev/ptyp 5.
Если вам действительно нужно поговорить с файлом под названием /dev/ttys2 , просто переместите старый /dev/ttys2 в сторону и сделайте символическую ссылку от ptyp5 до ttys2 .
Конечно, вы можете использовать другое число, кроме ptyp5 . Возможно, выберите один с большим числом, чтобы избежать дублирования, так как все ваши логин-терминалы также будут использовать ptys.
В дополнение к ответу @slonik.
Вы можете протестировать socat для создания виртуального последовательного порта, выполнив следующую процедуру (протестированную на Ubuntu 12.04):
Откройте терминал (позвоните ему Terminal 0) и выполните его:
Возвращенный код:
Откройте другой терминал и запишите (Terminal 1):
имя этого командного порта можно изменить в соответствии с ПК. это зависит от предыдущего выхода.
вы должны использовать номер, доступный в выделенной области.
Откройте другой терминал и запишите (Terminal 2):
Теперь вернемся к терминалу 1, и вы увидите строку “Test”.
Используйте для этого socat:
Существует также tty0tty http://sourceforge.net/projects/tty0tty/, который является настоящим эмулятором нулевого модема для Linux.
Это простой модуль ядра – небольшой исходный файл. Я не знаю, почему это только положило большие пальцы вниз на sourceforge, но это работает хорошо для меня. Самое лучшее в этом – это также эмулировать аппаратные контакты (RTC/CTS DSR/DTR). Он даже реализует команды TIOCMGET/TIOCMSET и TIOCMIWAIT iotcl!
В последнем ядре вы можете получить ошибки компиляции. Это легко исправить. Просто вставьте несколько строк вверху модуля /tty 0tty.c(после включения):
Когда модуль загружен, он создает 4 пары последовательных портов. Устройства:/dev/tnt0 to/dev/tnt7, где tnt0 подключен к tnt1, tnt2 подключен к tnt3 и т.д.
Возможно, вам придется исправить права доступа к файлам, чтобы использовать эти устройства.
Наверное, я был немного быстрым с моим энтузиазмом. Хотя водитель выглядит многообещающим, он кажется неустойчивым. Я не знаю точно, но я думаю, что он разбил машину в офисе, в котором я работал, из дома. Я не могу проверить, пока не вернусь в офис в понедельник.
Во-вторых, TIOCMIWAIT не работает. Код, как представляется, скопирован из некоторого “маленького tty” примера кода. Обработка TIOCMIWAIT кажется на месте, но она никогда не просыпается, потому что отсутствует соответствующий вызов wake_up_interruptible().
Авария в офисе действительно была ошибкой водителя. Произошла инициализация, и полностью непроверенный код TIOCMIWAIT вызвал сбой машины.
Я провел вчера и сегодня переписывал водителя. Было много проблем, но теперь это хорошо работает для меня. Отсутствует код для управления аппаратным потоком, управляемый драйвером, но мне он не нужен, потому что я сам буду управлять булавками, используя TIOCMGET/TIOCMSET/TIOCMIWAIT из кода режима пользователя.
Если кто-то интересуется моей версией кода, отправьте мне сообщение, и я пришлю его вам.
Вы можете посмотреть Tibbo VSPDL для создания виртуального последовательного порта linux с помощью драйвера ядра – это кажется довольно новым, и доступно для загрузки прямо сейчас (бета-версия). На данный момент не уверены в лицензии, или хотят ли они сделать ее доступной в коммерческих целях только в будущем.
Существуют и другие коммерческие альтернативы, такие как http://www.ttyredirector.com/.
В Open Source Remserial (GPL) также может делать то, что вы хотите, используя Unix PTY. Он передает последовательные данные в “сырой форме” в сетевой сокет; STTY-подобная настройка параметров терминала должна выполняться при создании порта, а изменение их позже, как описано в RFC 2217, похоже, не поддерживается. Вы должны иметь возможность запускать два экземпляра remserial для создания виртуального nullmodem, такого как com0com, за исключением того, что вам нужно заранее установить скорость порта и т.д.
Socat (также GPL) похож на расширенный вариант Remserial со многими другими опциями, включая метод PTY для перенаправления PTY к чему-то еще, что может быть другим примером Socat. Для юнитов, socat, вероятно, лучше, чем remserial, потому что вы можете напрямую вносить файлы в файл PTY. См. Пример PTY на странице руководства. A патч существует в разделе “contrib”, чтобы обеспечить поддержку RFC2217 для согласования настроек последовательной линии.
Используя ссылки, опубликованные в предыдущих ответах, я закодировал небольшой пример на С++, используя виртуальный последовательный порт. Я переместил код в GitHub: https://github.com/cymait/virtual-serial-port-example.
Код довольно понятен. Во-первых, вы создаете мастер-процесс, запустив мастер. /main, и он будет печатать на stderr, который использует устройство. После этого вы вызываете ведомое устройство. /main, где устройство является устройством, напечатанным в первой команде.
И что это. У вас есть двунаправленная связь между двумя процессами.
Используя этот пример, вы можете протестировать приложение, отправив все виды данных и посмотреть, работает ли он правильно.
Кроме того, вы всегда можете ссылаться на устройство, поэтому вам не нужно повторно компилировать тестируемое приложение.
Можно ли использовать USB- > RS232-адаптер? У меня есть несколько, и они просто используют драйвер FTDI. Затем вы должны иметь возможность переименовывать /dev/ttyUSB 0 (или что-то созданное) как/dev/ttyS2.
Я могу представить три варианта:
Внедрить RFC 2217
RFC 2217 охватывает COM-порт к стандарту TCP/IP, который позволяет клиенту в одной системе эмулировать последовательный порт для локальных программ, при этом прозрачная отправка и прием данных и сигналов управления на сервер в другой системе, которая фактически имеет последовательный порт. Здесь обзор высокого уровня.
Что бы вы сделали, это найти или реализовать клиентский COM-порт, который будет реализовывать клиентскую часть системы на вашем ПК – представляя собой настоящий последовательный порт, но на самом деле перенаправляет все на сервер. Вы можете получить этот драйвер бесплатно от Digi, Lantronix и т.д. В поддержку их реальных автономных серверов последовательных портов.
Затем вы затем реализуете серверную часть соединения локально в другой программе – позволяя клиенту подключаться и выдавать данные и команды управления по мере необходимости.
Это, вероятно, нетривиально, но RFC там, и вы можете найти проект с открытым исходным кодом, который реализует одну или обе стороны соединения.
Измените драйвер последовательного порта linux
В качестве альтернативы источник драйвера последовательного порта для Linux легко доступен. Возьмите это, обрезайте элементы управления аппаратным обеспечением и попросите один драйвер запустить два порта /dev/ttySx, как простой loopback. Затем подключите свою реальную программу к ttyS2 и вашему симулятору к другому ttySx.
Используйте два USB-кабеля с последовательным интерфейсом
Но самое легкое занятие прямо сейчас? Потратьте $40 на два USB-устройства с последовательным портом, соедините их вместе (нуль-модем) и фактически получите два реальных последовательных порта – один для тестируемой программы, один для вашего симулятора.
Источник
Настраиваем виртуальный компорт в Ubuntu
Удобно работать с виртуальной машиной 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 или «семёркой». Успехов!
Источник