简体   繁体   English

如何使用C查找Linux中哪个设备连接到USB串口?

[英]How to find which device is attached to a USB-serial port in Linux using C?

We are making a device and it has 8 serial ports. 我们正在制造一个设备,它有8个串口。 It runs on the Monta Vista Pro5 kernel. 它运行在Monta Vista Pro5内核上。 And we are working in C. 我们在C工作。

Suppose: A device gets attached to ttyUSB0, ttyUSB1 and ttyUSB2. 假设:设备连接到ttyUSB0,ttyUSB1和ttyUSB2。 The next device gets connected to ttyUSB3 and another to ttyUSB4. 下一个设备连接到ttyUSB3,另一个设备连接到ttyUSB4。 How can I know which device gets attached to which port ?? 我怎么知道哪个设备连接到哪个端口? ie ttyUSB0 or ttyUSB1 or so on. 即ttyUSB0或ttyUSB1等。 Is there a way to directly query the device and find which port it is attached to. 有没有办法直接查询设备并找到它所连接的端口。 Or, in C, open ttyUSB0, query it somehow and get some reply as to which device it is ?? 或者,在C中,打开ttyUSB0,以某种方式查询它并得到一些回复,它是什么设备?

A rather complicated way: do a stat of, say /dev/ttyUSB0. 一个相当复杂的方法:做一个统计,比如/ dev / ttyUSB0。 Get the device number. 获取设备编号。 And search for this in /proc/bus/usb/devices and find the vendor id or something to identify the device. 并在/ proc / bus / usb / devices中搜索并查找供应商ID或识别设备的内容。

Or: Is there some way to reserve ttyUSB0,ttyUSB1 and ttyUSB2 for one device, ttyUSB3 for another and so on when they are plugged in ? 或者:有没有办法为一个设备保留ttyUSB0,ttyUSB1和ttyUSB2,为其他设备保留ttyUSB3,等等什么时候插入? This way I will know which device is connected to which port. 这样我就知道哪个设备连接到哪个端口。

Help please..... :) 请帮忙..... :)

Thanks in advance. 提前致谢。 Nubin Stanley 努宾斯坦利

You can use udev rules to create symbolic links just to your device: 您可以使用udev规则仅为您的设备创建符号链接:

(these rules go in /etc/udev/rules.d/-name.rules -- look at your udev documentation (这些规则在/etc/udev/rules.d/-name.rules中 - 请查看您的udev文档

KERNEL=="ttyUSB*", ATTRS{idVendor}=="<vendorid>", MODE="0666", SYMLINK+="mydev"

You have to specify your vendor id and/or product id for your device. 您必须为设备指定供应商ID和/或产品ID。 Then those devices will be available at /dev/mydev in the above example. 然后,在上面的示例中,这些设备将在/ dev / mydev中可用。

You can also use various other parameters to create appropriate unique symbolic links for your use. 您还可以使用各种其他参数来创建适当的唯一符号链接供您使用。 Check udev man page. 检查udev手册页。

Here's my code, based on Alex Robinson's, but without global "except": 这是我的代码,基于Alex Robinson的,但没有全局“除”:

import os
from os.path import join

def find_tty_usb(idVendor, idProduct):
    """find_tty_usb('067b', '2302') -> '/dev/ttyUSB0'"""
    # Note: if searching for a lot of pairs, it would be much faster to search
    # for the enitre lot at once instead of going over all the usb devices
    # each time.
    for dnbase in os.listdir('/sys/bus/usb/devices'):
        dn = join('/sys/bus/usb/devices', dnbase)
        if not os.path.exists(join(dn, 'idVendor')):
            continue
        idv = open(join(dn, 'idVendor')).read().strip()
        if idv != idVendor:
            continue
        idp = open(join(dn, 'idProduct')).read().strip()
        if idp != idProduct:
            continue
        for subdir in os.listdir(dn):
            if subdir.startswith(dnbase+':'):
                for subsubdir in os.listdir(join(dn, subdir)):
                    if subsubdir.startswith('ttyUSB'):
                        return join('/dev', subsubdir)

This Python code seems to find the /dev/ttyUSB number for the given vendor ID and product ID. 此Python代码似乎找到给定供应商ID和产品ID的/ dev / ttyUSB编号。 Not hard to translate it to C. Parsing the output from hwinfo --usb can do the trick, too. 不难将其翻译为C.解析hwinfo --usb的输出也可以解决问题。 The regx is: 该regx是:

"\s\sVendor:\susb\s0x([0-9a-f]{4}).*?\s\sDevice:\susb\s0x([0-9a-f]{4}).*?\s\sDevice\sFile:\s/dev/ttyUSB([0-9]+)"
import  glob
import  os
import  re

def find_usb_tty(vendor_id = None, product_id = None) :
    tty_devs    = []

    for dn in glob.glob('/sys/bus/usb/devices/*') :
        try     :
            vid = int(open(os.path.join(dn, "idVendor" )).read().strip(), 16)
            pid = int(open(os.path.join(dn, "idProduct")).read().strip(), 16)
            if  ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) :
                dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*"))
                for sdn in dns :
                    for fn in glob.glob(os.path.join(sdn, "*")) :
                        if  re.search(r"\/ttyUSB[0-9]+$", fn) :
                            #tty_devs.append("/dev" + os.path.basename(fn))
                            tty_devs.append(os.path.join("/dev", os.path.basename(fn)))
                        pass
                    pass
                pass
            pass
        except ( ValueError, TypeError, AttributeError, OSError, IOError ) :
            pass
        pass

    return tty_devs

print find_usb_tty()

The best way to do this is would be to use libusb , but if that doesn't give you enough information about your devices (which it may not), then you'll have to use the /proc filesystem which the kernel makes available, specifically /proc/bus/usb/ . 执行此操作的最佳方法是使用libusb ,但如果这不能为您提供有关您的设备的足够信息(可能没有),那么您将不得不使用内核提供的/proc文件系统,特别是/proc/bus/usb/

Have a read of this information on /proc/bus/usb : in particular on /proc/bus/usb/devices . /proc/bus/usb上读取此信息 :特别是在/proc/bus/usb/devices But as you say, this is all a bit hacky! 但正如你所说,这一切都有点hacky!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM