在 Linux 中基于 USB VID:PID 获取设备路径

Get device path based on USB VID:PID in Linux

本文关键字:获取 PID 路径 VID Linux USB      更新时间:2023-10-16

如果我插入一个设备,比如说/dev/ttyUSB0,我想根据它的VID:PID(与lsusb一起找到)获取数字0,如何在C++Linux中做到这一点? 我有这个代码来查找一个打印机设备,如果它有帮助的话:

int printer_open (void)
{    
    char printer_location[] = "/dev/usb/lpX";
    struct stat buf;
    // continuously try all numbers until stat returns true for the connected printer
    for (int i = 0; i < 10; i++)
    {
        printer_location[11] = '0' + i;
        if (!stat (printer_location, &buf))
            break;
    }
    return 0;
}
你可以

使用libusb

apt-get install build-essential libudev-dev这里有一个很好的例子:
http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/
这是库的描述:
http://libusb.sourceforge.net/api-1.0/

int main() {
    libusb_context *context = NULL;
    libusb_device **list = NULL;
    int rc = 0;
    ssize_t count = 0;
    rc = libusb_init(&context);
    assert(rc == 0);
    count = libusb_get_device_list(context, &list);
    assert(count > 0);
    for (size_t idx = 0; idx < count; ++idx) {
        libusb_device *device = list[idx];
        libusb_device_descriptor desc = {0};
        rc = libusb_get_device_descriptor(device, &desc);
        assert(rc == 0);
        printf("Vendor:Device = %04x:%04xn", desc.idVendor, desc.idProduct);
    }
}

如果你编译你的代码,不要忘记添加 lib 引用-I/usr/include/libusb-1.0/- lusb-1.0

libusb实际上无法得到它。 所以请改为查看此文件:/proc/bus/input/devices

文件中的示例行:

I: Bus=0003 Vendor=1a2c Product=0c23 Version=0110
N: Name="USB USB Keyboard"
P: Phys=usb-0000:00:14.0-3/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/0003:1A2C:0C23.0015/input/input30
U: Uniq=
H: Handlers=sysrq kbd event10 leds
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff800000000007ff febeffdff3cfffff fffffffffffffffe
B: MSC=10
B: LED=7 

此函数从具有匹配 VID:PID 的设备获取事件编号:

#include <string>
#include <iostream>
#include <fstream>
void open_device (std::string device_vid, std::string device_pid)
{       
    try
    {
        std::ifstream file_input;
        std::size_t pos;
        std::string device_path, current_line, search_str, event_str;
        std::string device_list_file = "/proc/bus/input/devices";
        bool vid_pid_found = false;
        int fd = 0;
        bool debug = true;
        // 1. open device list file
        file_input.open(device_list_file.c_str());
        if (!file_input.is_open())
        {
            std::cerr << "file_input.open >> " << std::strerror(errno) << std::endl;
            throw -2;
        }
        // 2. search for first VID:PID and get event number
        search_str = "Vendor=" + device_vid + " Product=" + device_pid;
        while (getline(file_input, current_line))
        {
            if (!vid_pid_found)
            {
                pos = current_line.find(search_str, 0);
                if (pos != std::string::npos)
                {
                    vid_pid_found = true;
                    search_str = "event";
                }               
            }
            else
            {
                pos = current_line.find(search_str, 0);
                if (pos != std::string::npos)
                {
                    event_str = current_line.substr(pos);
                    // find space and substring event##
                    pos = event_str.find(' ', 0);
                    event_str = event_str.substr(0, pos);
                    break;
                }
            }
        }
        // 3.  build device path
        device_path = "/dev/input/" + event_str;
        if (debug) std::cout << "device_path = " << device_path << std::endl;   
        // 4.  connect to device
        fd = open (device_path.c_str(), O_RDONLY);
        if (fd < 0)
        {
            std::cerr << "open >> errno = " << std::strerror(errno) << std::endl;       
            throw -3;
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "e.what() = " << e.what() << std::endl;
        throw -1;
    }
    return;
}