Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/23: Рейтинг темы: голосов - 23, средняя оценка - 4.61
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
1

кроссплатформенный способ определения имен [активных] серийных портов (serial ports, COM1, /dev/ttyS0) и обращение к ним

12.10.2012, 03:11. Показов 4528. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нашел библиотеку Boost.Asio

http://www.boost.org/doc/libs/... ports.html

Она позволяет обращаться к серийным портам. Мне нужно для того чтобы написать программу, посылающую AT-команды модему. Вот только не знаю как по-нормальному получить список имен этих самых серийных портов, причем желательно активных, к которым подключены устройства. Пока у меня только один вариант: делать полный перебор всех возможных имен, и пытаться опрашивать их. Но дело в том, что например в линуксе спец файл девайса серийного порта вообще говоря может находиться в любом каталоге и даже не обязательно начинаться с ttyS (при желании пользователя, особенно если он вручную драйвера ставил и заводил модем).

В крайнем случае могу сделать отдельную реализацию этого процесса для Windows и для Linux. Но в таком случае скажите какие реализации лучше использовать из легко доступных в C++.

На форумах обычно не пишу, но в этом случае гугл упорно не помогает мне.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.10.2012, 03:11
Ответы с готовыми решениями:

Кроссплатформенный способ переноса файлов
Есть какой-нибудь легальный способ кроссплатформенного переноса папок/файлов в C++? Желательно...

Очистка экрана (кроссплатформенный способ)
Подскажите, пожалуйста, существует ли кроссплатформенный способ очистки экрана? в Windows я знаю...

Нужен кроссплатформенный способ работы с папками
Здравствуйте. Такая проблема: нужен кроссплатформенный способ работы с папками. Всё что нужно -...

Сканирование активных портов
Добрый день. Не могу найти/написать скрипт, который будет быстро сканировать порты и возвращать...

15
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.10.2012, 10:36 2
Цитата Сообщение от proxym Посмотреть сообщение
в линуксе спец файл девайса серийного порта вообще говоря может находиться в любом каталоге
для этого нужна переконфигурация/пересборка ядра. вряд ли кто в здравом уме станет такое делать.

Цитата Сообщение от proxym Посмотреть сообщение
даже не обязательно начинаться с ttyS
так же, маловероятно, что такой случай возможен в реальной жизни.

Цитата Сообщение от proxym Посмотреть сообщение
какие реализации лучше использовать из легко доступных в C++.
в с++ нет никаких реализаций для работы с COM портами. в чем вопрос?
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
12.10.2012, 11:28 3
Цитата Сообщение от niXman Посмотреть сообщение
для этого нужна переконфигурация/пересборка ядра. вряд ли кто в здравом уме станет такое делать.
Этим занимается udev

В Linux список устройств можно получить через dbus.
1
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.10.2012, 14:05 4
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Этим занимается udev
кстати да, это стало так после того, как появился udev.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
12.10.2012, 14:08 5
На ядрах 2.4 devfs.
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
12.10.2012, 17:35  [ТС] 6
Цитата Сообщение от niXman Посмотреть сообщение
Цитата Сообщение от proxym Посмотреть сообщение
даже не обязательно начинаться с ttyS
так же, маловероятно, что такой случай возможен в реальной жизни.
Еще как вероятно.
1) Серийный порт также может иметь например виды: /dev/ttyUSB0 /dev/ttyACM1 помимо /dev/ttyS0 https://www.redhat.com/mirrors... TO-11.html
2) Просто с /dev/tty может начинаться имя отнюдь не серийного порта, а псевдо терминала /dev/ttyp3, controlling terminal текущего процесса /dev/tty, терминала /dev/ttyI0 (кстати тоже может принимать команды модема), консоли /dev/tty0 http://www.tldp.org/HOWTO/Text... WTO-7.html

Добавлено через 4 минуты
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Этим занимается udev
В Linux список устройств можно получить через dbus.
Хорошо. Значит для Linux лучше всего udev, dbus для того что мне нужно. А в Windows?

Добавлено через 2 минуты
Цитата Сообщение от niXman Посмотреть сообщение
Цитата Сообщение от proxym Посмотреть сообщение
какие реализации лучше использовать из легко доступных в C++.
в с++ нет никаких реализаций для работы с COM портами. в чем вопрос?
В C++ Бьерна Страуструпа нет и Boost. Вопрос например в том, какие удобные готовые библиотеки существуют для этого?

Добавлено через 4 минуты
Цитата Сообщение от niXman Посмотреть сообщение
Цитата Сообщение от proxym Посмотреть сообщение
в линуксе спец файл девайса серийного порта вообще говоря может находиться в любом каталоге
для этого нужна переконфигурация/пересборка ядра. вряд ли кто в здравом уме станет такое делать.
Я не пересобирал ядро, у меня обычный Ubuntu Linux:
Код
proxym@ubuntu:~$ sudo mknod -m 666 /ttyS0 c 4 64
[sudo] password for proxym: 
proxym@ubuntu:~$ ls /
bin            dev         initrd.img.old  mnt   sbin     tmp    vmlinuz
boot           etc         lib             opt   selinux  ttyS0  vmlinuz.old
data_transfer  home        lost+found      proc  srv      usr
ddd.txt        initrd.img  media           root  sys      var
proxym@ubuntu:~$ ls -lsa /ttyS0 
0 crw-rw-rw- 1 root root 4, 64 2012-10-12 17:32 /ttyS0
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
12.10.2012, 17:51 7
Цитата Сообщение от proxym Посмотреть сообщение
Я не пересобирал ядро
я об этом уже писал, вряд ли кто в здравом уме станет такое делать.
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
12.10.2012, 17:56  [ТС] 8
Цитата Сообщение от niXman Посмотреть сообщение
я об этом уже писал, вряд ли кто в здравом уме станет такое делать.
ты писал более конкретно:
для этого нужна переконфигурация/пересборка ядра.
Если драйвер для линукса собран вручную (а это очень даже возможно в случае usb модемов) и возникли какие-то проблемы с созданием устройства, то пользователь еще как станет создавать устройство вручную, и он не обязан его именовать ни в соответствии ни с какими стандартами и создавать обязательно в каталоге /dev

Ладно так и быть. В моей программе будет дополнительная возможность вручную указать название порта. Это логично для тех кто вручную собирает драйвера =) Но авто обнаружение портов в обычном случае мне все равно нужно, поэтому вопрос открыт пока что.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
12.10.2012, 20:25 9
Цитата Сообщение от proxym Посмотреть сообщение
А в Windows?
Если верить доке, то оч. просто.
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
12.10.2012, 20:44  [ТС] 10
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Если верить доке, то оч. просто.
Это конечно здорово, но: "SerialPort::GetPortNames - метод .NET Framework 3.5"
Что-то мне совсем не хочется использовать .NET даже в виде такой реализации как Mono.
К тому же там с этим делом сплошные проблемы: весьма неадекватное поведение в разных ОС: http://stackoverflow.com/quest... -platforms
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
12.10.2012, 21:36  [ТС] 11
Так, я нагуглил реализацию через WinApi http://social.msdn.microsoft.c... bc2a263ea/
Вложения
Тип файла: txt serial_ports_winapi.txt (7.1 Кб, 28 просмотров)
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
12.10.2012, 21:55  [ТС] 12
Нашел еще 2 источника по теме:
1) EnumSerialPorts http://www.naughter.com/enumser.html
2) Simple Device Manager http://www.codeproject.com/Art... ce-Manager

Наверно пора начать пробовать =)
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
13.10.2012, 18:03  [ТС] 13
Касательно udev, dbus, hal...
Вот этот bash-скрипт показывает серийные устройства в линуксе:

Bash
1
2
3
for sport in $(hal-find-by-capability --capability serial) ; do
  hal-get-property --udi "${sport}" --key serial.device
done
Но говорят он показывает не все. Хотя у меня в общем-то показал все что надо.

Еще есть python скрипт.
Python
1
2
3
4
5
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")
Он возращает в принципе то же, что и команда "hal-find-by-capability --capability serial".

А вот кусочек кода на C:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
 
#include <linux/fs.h>
#include <linux/serial.h>
#include <linux/tty.h>
...
int fd;
struct serial_struct serinfo;
 
if ((fd = open(device, O_RDWR|O_NONBLOCK)) < 0) {
    perror(device);
    return;
}
if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) {
    perror("Cannot get serial info");
    close(fd);
    return;
}
После "fd = open (path, O_RDWR | O_NONBLOCK)"
нужно вызвать "ioctl (fd, TIOCGSERIAL, &serinfo)",
и если не будет ошибки, то серийное устройство (порт).
Это решение подходит для полного перебора по "/dev/tty*".

Другой вариант с использованием информации из каталога /sys и bash:
Bash
1
2
3
4
5
6
7
8
ll /sys/class/tty/*/device/driver
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyS0/device/driver -> ../../../bus/pnp/drivers/serial/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyS1/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyS2/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyS3/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyUSB0/device/driver -> ../../../../../../../bus/usb-serial/drivers/option1/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyUSB1/device/driver -> ../../../../../../../bus/usb-serial/drivers/option1/
lrwxrwxrwx 1 root root 0 2012-10-13 17:03 /sys/class/tty/ttyUSB2/device/driver -> ../../../../../../../bus/usb-serial/drivers/option1/
Читаем /usr/src/linux-*/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
Получаем еще один способ с использованием /proc и bash:
Bash
1
2
3
cat /proc/tty/drivers | grep serial
usbserial            /dev/ttyUSB   188 0-253 serial
serial               /dev/ttyS       4 64-111 serial
Использование информации из /dev/serial (может отсутствовать в старых ядрах, и директории /dev/serial не существует, если серийных портов нет вообще) и bash:
Bash
1
2
3
4
5
ls -l /dev/serial/by-id/
итого 0
lrwxrwxrwx 1 root root 23 2012-10-13 04:29 usb-HUAWEI_Technology_HUAWEI_Mobile-if00-port0 -> ../../ttyUSB_utps_modem
lrwxrwxrwx 1 root root 22 2012-10-13 04:29 usb-HUAWEI_Technology_HUAWEI_Mobile-if03-port0 -> ../../ttyUSB_utps_diag
lrwxrwxrwx 1 root root 22 2012-10-13 04:29 usb-HUAWEI_Technology_HUAWEI_Mobile-if04-port0 -> ../../ttyUSB_utps_pcui
В приложении пример готового решения на C++. Компилируется по команде: g++ serial.cpp -o serial
Готовый исполнимый файл выводит у меня:
/dev/ttyUSB2
/dev/ttyUSB1
/dev/ttyUSB0
/dev/ttyS0
Источник: http://stackoverflow.com/quest... ening-them
Вложения
Тип файла: txt serial.txt (3.3 Кб, 26 просмотров)
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
13.10.2012, 18:44  [ТС] 14
В случае попытки проверки USB-девайсов на то что они серийные получаем:
1) Нужны права рута для вызова: open((*it).c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY)
2) Вызов ioctl(fd, TIOCGSERIAL, &serinfo) не возвращает ноль об успешном выполнении вообще никак. errno возвращает номер 22: EINVAL (Invalid Argument). Забавно...
3) Поэтому автор той программки на C++, которую я привел во вложении к прошлому сообщению проверяет через ioctl только обычные серийные девайсы (с драйвером serial8250, но мне не нравится привязка к названию драйвера), а USB девайсы заносит в список без какой-либо проверки. Это не очень хорошо.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
14.10.2012, 16:44 15
Если ты внимательно читал доку, то там написано, что список доступных com портов храниться в реестре.
0
1 / 1 / 0
Регистрация: 22.04.2012
Сообщений: 30
14.10.2012, 20:06  [ТС] 16
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Если ты внимательно читал доку, то там написано, что список доступных com портов храниться в реестре.
Да. Я же писал:
Цитата Сообщение от proxym Посмотреть сообщение
Так, я нагуглил реализацию через WinApi http://social.msdn.microsoft.c... bc2a263ea/
- там про реестр.

Но далее я писал про Linux, в котором реестра естественно нет.
0
14.10.2012, 20:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.10.2012, 20:06
Помогаю со студенческими работами здесь

Кроссплатформенный вариант определения текущего времени
Привет, подскажите пожалуйста варианты платформонезависимого определения времени в данный момент....

Получение имён активных (залогиненных) пользователей на удалённом компьютере и их SID
Добрый день, знатоки! Прошу помочь разрешить следующую задачу: нужно узнать имя активного...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru