Jaki jest właściwy sposób uzyskania listy wszystkich dostępnych portów szeregowych / urządzeń w systemie Linux?
Innymi słowy, kiedy iteruję po wszystkich urządzeniach, w /dev/
jaki sposób mogę stwierdzić, które z nich są portami szeregowymi w klasyczny sposób, to znaczy te, które zwykle obsługują prędkości transmisji i kontrolę przepływu RTS / CTS ?
Rozwiązanie byłoby zakodowane w C.
Pytam, ponieważ używam biblioteki innej firmy, która robi to wyraźnie źle: wydaje się, że tylko iteruje /dev/ttyS*
. Problem polega na tym, że istnieją na przykład porty szeregowe przez USB (dostarczane przez adaptery USB-RS232), a te są wymienione w / dev / ttyUSB *. Czytając Serial-HOWTO na Linux.org , doszedłem do wniosku, że z czasem pojawią się również inne przestrzenie nazw.
Muszę więc znaleźć oficjalny sposób wykrywania urządzeń szeregowych. Problem w tym, że żadna z nich nie jest udokumentowana lub nie mogę jej znaleźć.
Wyobrażam sobie, że jednym ze sposobów byłoby otwarcie wszystkich plików z /dev/tty*
i wywołanie określonego ioctl()
z nich, który jest dostępny tylko na urządzeniach szeregowych. Czy byłoby to jednak dobre rozwiązanie?
Aktualizacja
hrickards zasugerował przyjrzenie się źródłu "setserial". Jego kod robi dokładnie to, co miałem na myśli:
Najpierw otwiera urządzenie z:
fd = open (path, O_RDWR | O_NONBLOCK)
Następnie wywołuje:
ioctl (fd, TIOCGSERIAL, &serinfo)
Jeśli to wywołanie nie zwróci żadnego błędu, to najwyraźniej jest to urządzenie szeregowe.
Znalazłem podobny kod w Serial Programming / termios , co sugerowało dodanie tej O_NOCTTY
opcji.
Jest jednak jeden problem z tym podejściem:
Kiedy testowałem ten kod na BSD Unix (czyli Mac OS X), również zadziałał. Jednak urządzenia szeregowe dostarczane przez Bluetooth powodują, że system (sterownik) próbuje połączyć się z urządzeniem Bluetooth, co zajmuje trochę czasu, zanim zwróci błąd przekroczenia limitu czasu. Jest to spowodowane po prostu otwarciem urządzenia. Mogę sobie wyobrazić, że podobne rzeczy mogą się zdarzyć również w Linuksie - w idealnym przypadku nie powinienem otwierać urządzenia, aby określić jego typ. Zastanawiam się, czy istnieje również sposób wywoływania ioctl
funkcji bez otwierania, czy też otwierania urządzenia w taki sposób, że nie powoduje to nawiązywania połączeń?
Co powinienem zrobić?
źródło
Odpowiedzi:
System
/sys
plików powinien zawierać dużo informacji dla twojego zadania. Mój system (2.6.32-40-generic # 87-Ubuntu) sugeruje:Który zawiera opisy wszystkich urządzeń TTY znanych w systemie. Skrócony przykład:
Po jednym z tych linków:
Tutaj
dev
plik zawiera te informacje:To jest węzeł główny / pomocniczy. Można je przeszukiwać w
/dev
katalogu, aby uzyskać nazwy przyjazne dla użytkownika:Katalog
/sys/class/tty
zawiera wszystkie urządzenia TTY, ale możesz chcieć wykluczyć te nieznośne wirtualne terminale i pseudoterminale. Proponuję zbadać tylko te, które majądevice/driver
wpis:źródło
/dev/zero
. Czy naprawdę myślisz, że to urządzenie szeregowe?W najnowszych jądrach (nie jestem pewien od kiedy) możesz wyświetlić zawartość / dev / serial, aby uzyskać listę portów szeregowych w twoim systemie. W rzeczywistości są to dowiązania symboliczne wskazujące na właściwy / dev / node:
Jak widać, to adapter USB-Serial. Zauważ, że jeśli w systemie nie ma portów szeregowych, katalog / dev / serial / nie istnieje. Mam nadzieję że to pomoże :).
źródło
Robię coś podobnego do następującego kodu. Działa z urządzeniami USB, a także z głupimi urządzeniami Serial8250, których wszyscy mamy 30 - ale tylko kilka z nich naprawdę działa.
Zasadniczo używam koncepcji z poprzednich odpowiedzi. Najpierw wylicz wszystkie urządzenia tty w / sys / class / tty /. Urządzenia, które nie zawierają podkatalogu / device, są odfiltrowywane. Takim urządzeniem jest / sys / class / tty / console. Następnie urządzenia faktycznie zawierające urządzenia są następnie akceptowane jako prawidłowy port szeregowy w zależności od celu sterownika-dowiązania symbolicznego fx.
i dla ttyS0
Wszystkie sterowniki sterowane przez serial8250 muszą być sondami używającymi wspomnianego wcześniej ioctl.
Prawidłowy jest tylko port zgłaszający prawidłowy typ urządzenia.
Pełne źródło do wyliczenia portów szeregowych wygląda następująco. Uzupełnienia są mile widziane.
źródło
Myślę, że znalazłem odpowiedź w dokumentacji źródła mojego jądra: /usr/src/linux-2.6.37-rc3/Documentation/filesystems/proc.txt
Oto link do tego pliku: http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob_plain;f=Documentation/filesystems/proc.txt;hb = e8883f8057c0f7c9950fa9f20568f37bfa62f34a
źródło
znalazłem
wykonywanie pracy.
źródło
setserial z opcją -g wydaje się robić to, co chcesz, a źródło C jest dostępne pod adresem http://www.koders.com/c/fid39344DABD14604E70DF1B8FEA7D920A94AF78BF8.aspx .
źródło
Nie mam tutaj urządzenia szeregowego, aby to przetestować, ale jeśli masz Pythona i dbus, możesz spróbować samemu.
Jeśli to się nie powiedzie, możesz przeszukać wewnątrz,
hwmanager_i.GetAllDevicesWithProperties()
aby sprawdzić, czy nazwa funkcji „serial”, którą właśnie odgadłem, ma inną nazwę.HTH
źródło
Nie mam urządzenia szeregowego USB, ale musi istnieć sposób na znalezienie rzeczywistych portów przy użyciu bezpośrednio bibliotek HAL:
Opublikowany kod python-dbus ani ten skrypt sh zawiera listę urządzeń bluetooth / dev / rfcomm *, więc nie jest to najlepsze rozwiązanie.
Zauważ, że na innych platformach unix porty szeregowe nie mają nazw ttyS? a nawet w Linuksie niektóre karty szeregowe pozwalają na nazwanie urządzeń. Zakładanie, że wzór w nazwach urządzeń szeregowych jest nieprawidłowy.
źródło
Użycie / proc / tty / drivers wskazuje tylko, które sterowniki tty są ładowane. Jeśli szukasz listy portów szeregowych, sprawdź / dev / serial, będzie ona zawierać dwa podkatalogi: według identyfikatora i ścieżki.
DAWNY:
Dzięki temu postowi: /superuser/131044/how-do-i-know-which-dev-ttys-is-my-serial-port
źródło
Moje podejście poprzez grupowe wybieranie numerów, aby każdy terminal z 'dialoutem' użytkownika pobierał
ls -l /dev/tty* | grep 'dialout'
tylko swój folderls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev
łatwe odsłuchiwanie wyjścia tty np. przy wyjściu szeregowym arduino:
head --lines 1 < /dev/ttyUSB0
słuchaj każdego tty tylko dla jednej linii:
for i in $(ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev); do head --lines 1 < $i; done
Bardzo podoba mi się podejście polegające na szukaniu sterowników:
ll /sys/class/tty/*/device/driver
Możesz teraz wybrać nazwę tty:
ls /sys/class/tty/*/device/driver | grep 'driver' | cut -d "/" -f 5
źródło
Biblioteka menedżera komunikacji szeregowej ma wiele interfejsów API i funkcji przeznaczonych dla żądanego zadania. Jeśli urządzenie to USB-UART, można użyć jego VID / PID. Jeśli urządzenie jest zgodne z BT-SPP, można używać interfejsów API specyficznych dla platformy. Spójrz na ten projekt dotyczący programowania portu szeregowego: https://github.com/RishiGupta12/serial-communication-manager
źródło
tak, wiem, spóźniłem się (jak zawsze). Oto mój fragment kodu (na podstawie odpowiedzi mk2). Może to komuś pomoże:
źródło