จะค้นหาอุปกรณ์อนุกรมทั้งหมด (ttyS, ttyUSB, .. ) บน Linux โดยไม่ต้องเปิดได้อย่างไร


113

วิธีที่เหมาะสมในการรับรายการพอร์ต / อุปกรณ์อนุกรมที่มีทั้งหมดบนระบบ 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) มันก็ใช้ได้เช่นกัน อย่างไรก็ตามอุปกรณ์อนุกรมที่ให้มาผ่านบลูทู ธ ทำให้ระบบ (ไดรเวอร์) พยายามเชื่อมต่อกับอุปกรณ์บลูทู ธ ซึ่งใช้เวลาสักครู่ก่อนที่จะกลับมาพร้อมกับข้อผิดพลาดการหมดเวลา สาเหตุนี้เกิดจากแค่เปิดเครื่อง และฉันสามารถจินตนาการได้ว่าสิ่งที่คล้ายกันนี้สามารถเกิดขึ้นได้บน Linux เช่นกัน - โดยหลักการแล้วฉันไม่จำเป็นต้องเปิดอุปกรณ์เพื่อดูประเภทของอุปกรณ์ ฉันสงสัยว่ามีวิธีเรียกใช้ioctlฟังก์ชันโดยไม่ต้องเปิดหรือเปิดอุปกรณ์ในลักษณะที่ไม่ทำให้เกิดการเชื่อมต่อหรือไม่?

ฉันควรทำอย่างไรดี?


1
มีคนที่ไม่ระบุชื่อแนะนำการแก้ไขนี้ซึ่งถูกปฏิเสธดังนั้นฉันจึงทิ้งไว้ที่นี่เป็นความคิดเห็นแทน: หากคุณใช้แฟล็ก TIOCGSERIAL ในการเรียก ioctl แทนที่จะเป็น TIOCMGET การโทรจะไม่ส่งคืนข้อผิดพลาดด้วยเส้นทางที่ไม่ถูกต้องบางอย่างที่ไม่ อ้างถึงพอร์ต COM (อนุกรม) ด้วยแฟล็ก TIOCMGET ioctl จะทำงานเฉพาะกับพอร์ต COM ที่มีให้เข้าถึงทั้งในเส้นทางที่เป็นไปได้ของ TTY และ TTYUSB
Thomas Tempelmann

คำตอบ:


78

/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/ttydir มีอุปกรณ์ 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/

@entalpi /dev/zeroคุณจะได้รับคำ คุณคิดว่านี่เป็นอุปกรณ์อนุกรมหรือไม่?
AH

การค้นหาใน / dev ไม่มีประโยชน์เนื่องจากคุณมีชื่อใน / sys / class / tty อยู่แล้ว (ตามค่าเริ่มต้น udev จะสร้างโหนด / dev / DEVNAME) สิ่งที่คุณสนใจคือลิงก์ "สัญลักษณ์" ใด ๆ ใน / dev ที่ชี้ไปยังอุปกรณ์ดังกล่าว หายากกว่านี้มาก
xryl669

28

ในเมล็ดล่าสุด (ไม่แน่ใจว่าตั้งแต่เมื่อไหร่) คุณสามารถแสดงรายการเนื้อหาของ / dev / serial เพื่อรับรายการพอร์ตอนุกรมในระบบของคุณ จริงๆแล้วพวกเขาเป็น symlink ที่ชี้ไปยัง / dev / node ที่ถูกต้อง:

flu0@laptop:~$ ls /dev/serial/
total 0
drwxr-xr-x 2 root root 60 2011-07-20 17:12 by-id/
drwxr-xr-x 2 root root 60 2011-07-20 17:12 by-path/
flu0@laptop:~$ ls /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 2011-07-20 17:12 usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 -> ../../ttyUSB0
flu0@laptop:~$ ls /dev/serial/by-path/
total 0
lrwxrwxrwx 1 root root 13 2011-07-20 17:12 pci-0000:00:0b.0-usb-0:3:1.0-port0 -> ../../ttyUSB0

นี่คืออะแดปเตอร์ USB-Serial อย่างที่คุณเห็น โปรดทราบว่าเมื่อไม่มีพอร์ตอนุกรมบนระบบไดเร็กทอรี / dev / serial / จะไม่มีอยู่ หวังว่านี่จะช่วยได้ :)


3
นี่คือฟังก์ชั่นของ udev (โดยเฉพาะการกำหนดค่าใน /lib/udev/rules.d/??-persistent-serial.rules) ซึ่งเปิดตัวใน 2.5
ergosys

4
เคล็ดลับดีๆ! น่าเสียดายที่ฉันไม่คิดว่าสิ่งนี้จะแสดงในพอร์ตอนุกรมในตัวมีเพียงพอร์ตอนุกรม USB (ดูโดย udev เมื่อเชื่อมต่อ) ฉันไม่เห็นอะไรเลยสำหรับ / dev / serial ใน Ubuntu 14 ใน VMware VM (พร้อม ttyS0 / COM1 ที่ VM ให้มา) และกฎ udev (60-persistent-serial.rules) กำลังดูเฉพาะอุปกรณ์ udev - ฉันไม่คิดว่า udev จะรู้เกี่ยวกับพอร์ตอนุกรม ttyS * "ในตัว" แต่จะต้องทดสอบด้วย ioctl หรือคล้ายกับคำตอบอื่น ๆ
Reed Hedges

ls / dev / serial / ls: ไม่สามารถเข้าถึง '/ dev / serial /': ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว Slackware 14.2 ปัจจุบัน x64
jpka

2
@jpka: จะเกิดขึ้นหากไม่มีอุปกรณ์อนุกรมให้ค้นหา ฉันทำตามข้างต้นและได้ผล จากนั้นฉันก็ถอดปลั๊กอุปกรณ์อนุกรม (FTDI) ของฉันออกจาก USB และหลังจากนั้นก็เกิดข้อผิดพลาดตามที่คุณอธิบาย
Warpspace

13

ฉันกำลังทำโค้ดต่อไปนี้ ใช้งานได้กับอุปกรณ์ USB และ serial8250-devuices โง่ ๆ ที่เรามีทั้งหมด 30 ตัว แต่มีเพียงไม่กี่ตัวเท่านั้นที่ใช้งานได้จริง

โดยทั่วไปฉันใช้แนวคิดจากคำตอบก่อนหน้านี้ ก่อนอื่นให้ระบุอุปกรณ์ tty ทั้งหมดใน / sys / class / tty / อุปกรณ์ที่ไม่มี a / device subdir จะถูกกรองออกไป / sys / class / tty / console เป็นอุปกรณ์ดังกล่าว จากนั้นอุปกรณ์ที่มีอุปกรณ์จริง ๆ แล้วจึงได้รับการยอมรับว่าเป็นพอร์ตอนุกรมที่ถูกต้องขึ้นอยู่กับเป้าหมายของไดรเวอร์ symlink fx

$ ls -al /sys/class/tty/ttyUSB0//device/driver
lrwxrwxrwx 1 root root 0 sep  6 21:28 /sys/class/tty/ttyUSB0//device/driver -> ../../../bus/platform/drivers/usbserial

และสำหรับ ttyS0

$ ls -al /sys/class/tty/ttyS0//device/driver
lrwxrwxrwx 1 root root 0 sep  6 21:28 /sys/class/tty/ttyS0//device/driver -> ../../../bus/platform/drivers/serial8250

ไดรเวอร์ทั้งหมดที่ขับเคลื่อนด้วย serial8250 ต้องเป็นโพรบที่ใช้ ioctl ที่กล่าวถึงก่อนหน้านี้

        if (ioctl(fd, TIOCGSERIAL, &serinfo)==0) {
            // If device type is no PORT_UNKNOWN we accept the port
            if (serinfo.type != PORT_UNKNOWN)
                the_port_is_valid

เฉพาะพอร์ตที่รายงานประเภทอุปกรณ์ที่ถูกต้องเท่านั้นที่ถูกต้อง

แหล่งที่มาที่สมบูรณ์สำหรับการแจกแจง serialports มีลักษณะดังนี้ เพิ่มเติมยินดีต้อนรับ

#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/serial.h>

#include <iostream>
#include <list>

using namespace std;

static string get_driver(const string& tty) {
    struct stat st;
    string devicedir = tty;

    // Append '/device' to the tty-path
    devicedir += "/device";

    // Stat the devicedir and handle it if it is a symlink
    if (lstat(devicedir.c_str(), &st)==0 && S_ISLNK(st.st_mode)) {
        char buffer[1024];
        memset(buffer, 0, sizeof(buffer));

        // Append '/driver' and return basename of the target
        devicedir += "/driver";

        if (readlink(devicedir.c_str(), buffer, sizeof(buffer)) > 0)
            return basename(buffer);
    }
    return "";
}

static void register_comport( list<string>& comList, list<string>& comList8250, const string& dir) {
    // Get the driver the device is using
    string driver = get_driver(dir);

    // Skip devices without a driver
    if (driver.size() > 0) {
        string devfile = string("/dev/") + basename(dir.c_str());

        // Put serial8250-devices in a seperate list
        if (driver == "serial8250") {
            comList8250.push_back(devfile);
        } else
            comList.push_back(devfile); 
    }
}

static void probe_serial8250_comports(list<string>& comList, list<string> comList8250) {
    struct serial_struct serinfo;
    list<string>::iterator it = comList8250.begin();

    // Iterate over all serial8250-devices
    while (it != comList8250.end()) {

        // Try to open the device
        int fd = open((*it).c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY);

        if (fd >= 0) {
            // Get serial_info
            if (ioctl(fd, TIOCGSERIAL, &serinfo)==0) {
                // If device type is no PORT_UNKNOWN we accept the port
                if (serinfo.type != PORT_UNKNOWN)
                    comList.push_back(*it);
            }
            close(fd);
        }
        it ++;
    }
}

list<string> getComList() {
    int n;
    struct dirent **namelist;
    list<string> comList;
    list<string> comList8250;
    const char* sysdir = "/sys/class/tty/";

    // Scan through /sys/class/tty - it contains all tty-devices in the system
    n = scandir(sysdir, &namelist, NULL, NULL);
    if (n < 0)
        perror("scandir");
    else {
        while (n--) {
            if (strcmp(namelist[n]->d_name,"..") && strcmp(namelist[n]->d_name,".")) {

                // Construct full absolute file path
                string devicedir = sysdir;
                devicedir += namelist[n]->d_name;

                // Register the device
                register_comport(comList, comList8250, devicedir);
            }
            free(namelist[n]);
        }
        free(namelist);
    }

    // Only non-serial8250 has been added to comList without any further testing
    // serial8250-devices must be probe to check for validity
    probe_serial8250_comports(comList, comList8250);

    // Return the lsit of detected comports
    return comList;
}


int main() {
    list<string> l = getComList();

    list<string>::iterator it = l.begin();
    while (it != l.end()) {
        cout << *it << endl;
        it++;
    }

    return 0;   
}

ลิงค์เดียวถือเป็นคำตอบที่ไม่ดีเนื่องจากไม่มีความหมายในตัวเองและไม่รับประกันว่าทรัพยากรเป้าหมายจะมีชีวิตอยู่ในอนาคต โปรดพยายามรวมข้อมูลสรุปอย่างน้อยที่คุณกำลังเชื่อมโยงไปถึง
j0k

ต้องขอบคุณ Soren สำหรับสิ่งนี้แม้ว่าเราจะรู้จัก API และแนวคิดบางอย่างเกี่ยวกับเรื่องนี้ แต่คุณทำได้ดีมาก Soren ขอบคุณอีกครั้ง
ind79ra

12

ฉันคิดว่าฉันพบคำตอบในเอกสารซอร์สเคอร์เนลของฉัน: /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


ใช่ดูเหมือนว่าจะใช้งานได้ อย่างไรก็ตามโซลูชันนี้ต้องการให้ฉันอ่านไฟล์ข้อความและแยกวิเคราะห์ ฉันสงสัยว่ามีสิ่งที่ดีกว่าหรือไม่เช่น API ที่ช่วยให้ฉันได้รับเนื้อหาเหล่านี้ในรูปแบบไบนารีที่มีโครงสร้าง
Thomas Tempelmann


3

setserial กับตัวเลือกปรากฏ -g จะทำในสิ่งที่คุณต้องการและที่มา C สามารถใช้ได้ที่http://www.koders.com/c/fid39344DABD14604E70DF1B8FEA7D920A94AF78BF8.aspx


ฉันดูรหัสและมีข้อบกพร่องที่ฉันอธิบายในคำถามของฉันในตอนท้ายเนื่องจากต้องเปิดอุปกรณ์ซึ่งอาจนำไปสู่การพยายามเชื่อมต่อซึ่งในทางกลับกันก็ไม่ดี แต่บางทีไดรเวอร์ Linux อาจฉลาดกว่าไดรเวอร์ OSX ปัจจุบันเมื่อพูดถึงการรองรับบลูทู ธ เนื่องจากพวกเขาจะไม่เปิดการเชื่อมต่อทันที? ใครจะรู้? บางทีฉันควรจะเริ่มคำถามใหม่เพื่อชี้แจงโดยเฉพาะ หากปรากฎว่าไม่เป็นไรฉันก็ยอมรับคำตอบของคุณที่นี่เช่นกัน อืมม ...
Thomas Tempelmann

3

ฉันไม่มีอุปกรณ์อนุกรมที่จะทดสอบ แต่ถ้าคุณมี 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()เพื่อดูว่าชื่อความสามารถ "อนุกรม" ที่ฉันเพิ่งเดามีชื่ออื่นหรือไม่

HTH


2

ฉันไม่มีอุปกรณ์อนุกรม USB แต่ต้องมีวิธีค้นหาพอร์ตจริงโดยใช้ไลบรารี HAL โดยตรง:

====================================================================
#! /usr/bin/env bash
#
# Uses HAL to find existing serial hardware
#

for sport in $(hal-find-by-capability --capability serial) ; do
  hal-get-property --udi "${sport}" --key serial.device
done

====================================================================

รหัส python-dbus ที่โพสต์หรือสคริปต์ sh นี้แสดงรายการอุปกรณ์ bluetooth / dev / rfcomm * ดังนั้นจึงไม่ใช่ทางออกที่ดีที่สุด

โปรดทราบว่าบนแพลตฟอร์มยูนิกซ์อื่น ๆ พอร์ตอนุกรมไม่มีชื่อ ttyS? และแม้กระทั่งใน linux การ์ดซีเรียลบางตัวอนุญาตให้คุณตั้งชื่ออุปกรณ์ได้ สมมติว่ารูปแบบในชื่ออุปกรณ์อนุกรมไม่ถูกต้อง


น่าเสียดายที่ HAL ถูกลบออกจาก Ubuntu (หลัง 12.04) มีเครื่องมือที่ใช้งานง่ายที่ดี ไม่มีใครทราบว่ามีการทดแทนข้างต้นหรือไม่? แต่ถ้าคุณใช้เวอร์ชัน / distro ที่มี HAL สิ่งนี้ก็ดูดี
Reed Hedges

2

การใช้ / proc / tty / ไดรเวอร์ระบุเฉพาะไดรเวอร์ 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

ขอบคุณโพสต์นี้: /superuser/131044/how-do-i-know-which-dev-ttys-is-my-serial-port


เห็นได้ชัดว่านี่ขึ้นอยู่กับระยะห่าง ฉันไม่พบ / dev / serial ในกล่องของฉัน (ใช้ Debian)
SimonC

0

วิธีการของฉันผ่านทางกลุ่มdialoutที่จะได้รับ TTY กับผู้ใช้ dialout 'ทุก ls -l /dev/tty* | grep 'dialout' ที่จะได้รับโฟลเดอร์ของ ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev

ง่ายต่อการฟังเอาต์พุต tty เช่นเมื่อ arduino serial out: head --lines 1 < /dev/ttyUSB0

ฟังทุก tty out เพียงบรรทัดเดียว: 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 ได้ทันที: ls /sys/class/tty/*/device/driver | grep 'driver' | cut -d "/" -f 5


0

ไลบรารีตัวจัดการการสื่อสารแบบอนุกรมมี API และคุณลักษณะมากมายสำหรับงานที่คุณต้องการ หากอุปกรณ์เป็น USB-UART สามารถใช้ VID / PID ได้ หากอุปกรณ์เป็น BT-SPP เกินกว่าที่ API เฉพาะแพลตฟอร์มจะสามารถใช้ได้ ดูโครงการนี้สำหรับการเขียนโปรแกรมพอร์ตอนุกรม: https://github.com/RishiGupta12/serial-communication-manager


0

ใช่ฉันรู้ว่าฉันสายเกินไป (เช่นเคย) นี่คือโค้ดของฉัน (อ้างอิงจากการตอบกลับของ mk2) สิ่งนี้อาจช่วยใครบางคนได้:

std::vector<std::string> find_serial_ports()
{
 std::vector<std::string> ports;
    std::filesystem::path kdr_path{"/proc/tty/drivers"};
    if (std::filesystem::exists(kdr_path))
    {
        std::ifstream ifile(kdr_path.generic_string());
        std::string line;
        std::vector<std::string> prefixes;
        while (std::getline(ifile, line))
        {
            std::vector<std::string> items;
            auto it = line.find_first_not_of(' ');
            while (it != std::string::npos)
            {

                auto it2 = line.substr(it).find_first_of(' ');
                if (it2 == std::string::npos)
                {
                    items.push_back(line.substr(it));
                    break;
                }
                it2 += it;
                items.push_back(line.substr(it, it2 - it));
                it = it2 + line.substr(it2).find_first_not_of(' ');
            }
            if (items.size() >= 5)
            {
                if (items[4] == "serial" && items[0].find("serial") != std::string::npos)
                {
                    prefixes.emplace_back(items[1]);
                }
            }
        }
        ifile.close();
        for (auto& p: std::filesystem::directory_iterator("/dev"))
        {
            for (const auto& pf : prefixes)
            {
                auto dev_path = p.path().generic_string();
                if (dev_path.size() >= pf.size() && std::equal(dev_path.begin(), dev_path.begin() + pf.size(), pf.begin()))
                {
                    ports.emplace_back(dev_path);
                }
            }
        }
    }
    return ports;
}

ดูเหมือนว่าโค้ดของคุณจะแยกวิเคราะห์คำตอบที่stackoverflow.com/a/4701610/43615อ้างถึง ถ้าเป็นเช่นนั้นคุณจะพูดถึงสิ่งนั้นในการตอบกลับของคุณได้ไหม
โทมัส Tempelmann
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.