Как правильно получить список всех доступных последовательных портов / устройств в системе Linux?
Другими словами, когда я перебираю все устройства /dev/
, как мне классическим способом определить, какие из них являются последовательными, то есть те, которые обычно поддерживают скорость передачи данных и управление потоком RTS / CTS ?
Решение будет закодировано на C.
Я спрашиваю, потому что я использую стороннюю библиотеку, которая явно ошибается: кажется, что она только повторяется /dev/ttyS*
. Проблема в том, что есть, например, последовательные порты через USB (предоставляемые адаптерами USB-RS232), и они перечислены в / dev / ttyUSB *. И читая Serial-HOWTO на Linux.org , я понимаю, что со временем появятся и другие пространства имен.
Поэтому мне нужно найти официальный способ обнаружения последовательных устройств. Проблема в том, что ничего не задокументировано, или я не могу его найти.
Я предполагаю, что одним из способов было бы открыть все файлы /dev/tty*
и вызвать ioctl()
на них определенный, который доступен только на последовательных устройствах. Но будет ли это хорошим решением?
Обновить
hrickards предложил посмотреть исходник "setserial". Его код делает именно то, что я имел в виду:
Сначала он открывает устройство с:
fd = open (path, O_RDWR | O_NONBLOCK)
Затем он вызывает:
ioctl (fd, TIOCGSERIAL, &serinfo)
Если этот вызов не возвращает ошибки, значит, это, по-видимому, последовательное устройство.
Я нашел похожий код в Serial Programming / termios , который также предложил добавить эту O_NOCTTY
опцию.
Однако у этого подхода есть одна проблема:
Когда я тестировал этот код в BSD Unix (то есть в Mac OS X), он тоже работал. Однако последовательные устройства, которые предоставляются через Bluetooth, заставляют систему (драйвер) пытаться подключиться к устройству Bluetooth, что занимает некоторое время, прежде чем оно вернется с ошибкой тайм-аута. Это вызвано простым открытием устройства. И я могу представить, что подобное может происходить и в Linux - в идеале мне не нужно открывать устройство, чтобы определить его тип. Интересно, есть ли способ вызывать ioctl
функции без открытия или открывать устройство таким образом, чтобы это не приводило к установлению соединений?
Что я должен делать?
источник
Ответы:
/sys
Файловая система должна содержать вволю информацию для ваших поисков. Моя система (2.6.32-40-generic # 87-Ubuntu) предлагает:Это дает вам описания всех устройств TTY, известных системе. Урезанный пример:
По одной из этих ссылок:
Здесь
dev
файл содержит эту информацию:Это главный / второстепенный узел. Их можно искать в
/dev
каталоге, чтобы получить удобные имена:/sys/class/tty
Реж содержит все устройства TTY , но вы можете захотеть , чтобы исключить те досадные виртуальные терминалы и псевдо - терминалы. Предлагаю вам изучить только те, в которых естьdevice/driver
запись:источник
/dev/zero
. Вы правда думаете, что это серийное устройство?В последних ядрах (не знаю, с каких пор) вы можете перечислить содержимое / dev / serial, чтобы получить список последовательных портов в вашей системе. На самом деле это символические ссылки, указывающие на правильный / dev / node:
Как видите, это адаптер USB-Serial. Обратите внимание, что если в системе нет последовательных портов, каталог / dev / serial / не существует. Надеюсь это поможет :).
источник
Я делаю что-то вроде следующего кода. Он работает с USB-устройствами, а также с тупыми serial8250-устройствами, которых у всех нас 30, но только пара из них действительно работает.
В основном я использую концепцию из предыдущих ответов. Сначала перечислите все tty-устройства в / sys / class / tty /. Устройства, не содержащие подкаталог / device, отфильтровываются. / sys / class / tty / console - такое устройство. Затем устройства, фактически содержащие устройства, затем принимаются как действительный последовательный порт в зависимости от цели символической ссылки драйвера fx.
а для ttyS0
Все драйверы, управляемые serial8250, должны быть зондами, использующими ранее упомянутый ioctl.
Действителен только порт, сообщающий о допустимом типе устройства.
Полный исходный код для перечисления последовательных портов выглядит так. Дополнения приветствуются.
источник
Думаю, я нашел ответ в исходной документации ядра: /usr/src/linux-2.6.37-rc3/Documentation/filesystems/proc.txt
Вот ссылка на этот файл: http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob_plain;f=Documentation/filesystems/proc.txt;hb = e8883f8057c0f7c9950fa9f20568f37bfa62f34a
источник
я нашел
делаю работу.
источник
setserial с параметром -g, похоже, делает то, что вы хотите, а исходный код C доступен по адресу http://www.koders.com/c/fid39344DABD14604E70DF1B8FEA7D920A94AF78BF8.aspx .
источник
У меня нет последовательного устройства, чтобы проверить это, но если у вас есть python и dbus, вы можете попробовать это самостоятельно.
Если это не удается, вы можете поискать внутри
hwmanager_i.GetAllDevicesWithProperties()
чтобы увидеть, имеет ли имя возможности «серийный», которое я только что предположил, другое имя.НТН
источник
У меня нет последовательного USB-устройства, но должен быть способ найти настоящие порты напрямую с помощью библиотек HAL:
Опубликованный код python-dbus и этот сценарий sh не перечисляют устройства bluetooth / dev / rfcomm *, поэтому это не лучшее решение.
Обратите внимание, что на других платформах unix последовательные порты не называются ttyS? и даже в Linux некоторые последовательные карты позволяют вам присваивать имена устройствам. Предполагать, что шаблон в именах последовательных устройств неверен.
источник
Использование / proc / tty / drivers указывает только на то, какие драйверы tty загружены. Если вы ищете список последовательных портов, проверьте / dev / serial, он будет иметь два подкаталога: по идентификатору и по пути.
EX:
Благодаря этому сообщению: /superuser/131044/how-do-i-know-which-dev-ttys-is-my-serial-port
источник
Мой подход через групповой дозвон, чтобы получить каждый терминал с помощью дозвона пользователя,
ls -l /dev/tty* | grep 'dialout'
чтобы получить только свою папкуls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev
легко прослушать вывод tty, например, при последовательном выходе Arduino:
head --lines 1 < /dev/ttyUSB0
прослушивать каждый tty только для одной строки:
for i in $(ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev); do head --lines 1 < $i; done
Мне очень нравится подход поиска драйверов:
ll /sys/class/tty/*/device/driver
Теперь вы можете выбрать tty-Name:
ls /sys/class/tty/*/device/driver | grep 'driver' | cut -d "/" -f 5
источник
Библиотека диспетчера последовательной связи имеет множество API и функций, предназначенных для решения вашей задачи. Если устройство представляет собой USB-UART, можно использовать его VID / PID. Если используется устройство BT-SPP, можно использовать API, специфичные для платформы. Взгляните на этот проект для программирования последовательного порта: https://github.com/RishiGupta12/serial-communication-manager
источник
да, я знаю, я опоздал (как всегда). Вот мой фрагмент кода (на основе ответа mk2). Может быть, это кому-то поможет:
источник