устройств - работа с com портом linux




Как найти все последовательные устройства(ttyS, ttyUSB,..) на Linux, не открывая их? (8)

seterial с параметром -g, похоже, делает то, что вы хотите, а источник C доступен по адресу http://www.koders.com/c/fid39344DABD14604E70DF1B8FEA7D920A94AF78BF8.aspx .

Каков правильный способ получить список всех доступных последовательных портов / устройств в системе 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 без открытия или открыть устройство таким образом, чтобы он не вызывал соединений?

Что мне делать?


Библиотека диспетчера последовательной связи имеет множество API и функций, предназначенных для требуемой задачи. Если устройство является USB-UART, его VID / PID можно использовать. Если устройство BT-SPP, то могут использоваться интерфейсы API платформы. Взгляните на этот проект для программирования последовательного порта github.com/RishiGupta12/serial-communication-manager


Использование / proc / tty / drivers указывает только, какие драйверы tty загружены. Если вы ищете список последовательных портов, проверьте / dev / serial, у него будет два подкаталога: by-id и by-path.

EX:

# find . -type l
./by-path/usb-0:1.1:1.0-port0
./by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0

Благодаря этому сообщению: https://superuser.com/questions/131044/how-do-i-know-which-dev-ttys-is-my-serial-port


Мой подход через групповой набор, чтобы получить каждый tty с пользовательским «номером» ls -l /dev/tty* | grep 'dialout' ls -l /dev/tty* | grep 'dialout' чтобы получить только папку ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev

легко прослушивать выход tty, например, когда серийный выход head --lines 1 < /dev/ttyUSB0 : 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 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 ls /sys/class/tty/*/device/driver | grep 'driver' | cut -d "/" -f 5


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

import dbus
bus = dbus.SystemBus()
hwmanager = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hwmanager_i = dbus.Interface(hwmanager, 'org.freedesktop.Hal.Manager')
print hwmanager_i.FindDeviceByCapability("serial")

Если это не удается, вы можете hwmanager_i.GetAllDevicesWithProperties() поиск внутри hwmanager_i.GetAllDevicesWithProperties() чтобы узнать, имеет ли имя функции «serial», которое я только что догадался, другое имя.

НТН


Файловая система /sys должна содержать много информации для вашего квеста. Моя система (2.6.32-40-generic # 87-Ubuntu) предлагает:

/sys/class/tty

Что дает вам описания всех устройств TTY, известных системе. Урезанный пример:

# ll /sys/class/tty/ttyUSB*
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 /sys/class/tty/ttyUSB0 -> ../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0/ttyUSB0/tty/ttyUSB0/
lrwxrwxrwx 1 root root 0 2012-03-28 20:44 /sys/class/tty/ttyUSB1 -> ../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/ttyUSB1/tty/ttyUSB1/

Следуя одной из этих ссылок:

# ll /sys/class/tty/ttyUSB0/
insgesamt 0
drwxr-xr-x 3 root root    0 2012-03-28 20:43 ./
drwxr-xr-x 3 root root    0 2012-03-28 20:43 ../
-r--r--r-- 1 root root 4096 2012-03-28 20:49 dev
lrwxrwxrwx 1 root root    0 2012-03-28 20:43 device -> ../../../ttyUSB0/
drwxr-xr-x 2 root root    0 2012-03-28 20:49 power/
lrwxrwxrwx 1 root root    0 2012-03-28 20:43 subsystem -> ../../../../../../../../../../class/tty/
-rw-r--r-- 1 root root 4096 2012-03-28 20:43 uevent

Здесь файл dev содержит следующую информацию:

# cat /sys/class/tty/ttyUSB0/dev
188:0

Это основной / младший узел. Их можно найти в каталоге /dev чтобы получить удобные имена:

# ll -R /dev |grep "188, *0"
crw-rw----   1 root dialout 188,   0 2012-03-28 20:44 ttyUSB0

В /sys/class/tty содержатся все устройства TTY, но вы можете исключить эти досадные виртуальные терминалы и псевдотерминалы. Я предлагаю вам изучить только те, у которых есть запись device/driver :

# ll /sys/class/tty/*/device/driver
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS0/device/driver -> ../../../bus/pnp/drivers/serial/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS1/device/driver -> ../../../bus/pnp/drivers/serial/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS2/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS3/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 /sys/class/tty/ttyUSB0/device/driver -> ../../../../../../../../bus/usb-serial/drivers/ftdi_sio/
lrwxrwxrwx 1 root root 0 2012-03-28 21:15 /sys/class/tty/ttyUSB1/device/driver -> ../../../../../../../../bus/usb-serial/drivers/ftdi_sio/

Я думаю, что нашел ответ в моей исходной документации ядра: /usr/src/linux-2.6.37-rc3/Documentation/filesystems/proc.txt

1.7 TTY info in /proc/tty
-------------------------

Information about  the  available  and actually used tty's can be found in the
directory /proc/tty.You'll  find  entries  for drivers and line disciplines in
this directory, as shown in Table 1-11.


Table 1-11: Files in /proc/tty
..............................................................................
 File          Content                                        
 drivers       list of drivers and their usage                
 ldiscs        registered line disciplines                    
 driver/serial usage statistic and status of single tty lines 
..............................................................................

To see  which  tty's  are  currently in use, you can simply look into the file
/proc/tty/drivers:

  > cat /proc/tty/drivers 
  pty_slave            /dev/pts      136   0-255 pty:slave 
  pty_master           /dev/ptm      128   0-255 pty:master 
  pty_slave            /dev/ttyp       3   0-255 pty:slave 
  pty_master           /dev/pty        2   0-255 pty:master 
  serial               /dev/cua        5   64-67 serial:callout 
  serial               /dev/ttyS       4   64-67 serial 
  /dev/tty0            /dev/tty0       4       0 system:vtmaster 
  /dev/ptmx            /dev/ptmx       5       2 system 
  /dev/console         /dev/console    5       1 system:console 
  /dev/tty             /dev/tty        5       0 system:/dev/tty 
  unknown              /dev/tty        4    1-63 console 

Вот ссылка на этот файл: http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob_plain;f=Documentation/filesystems/proc.txt;hb=e8883f8057c0f7c9950fa9f20568f37bfa62f34a


я нашел

dmesg | grep tty

выполняя эту работу.





serial-port