2

How to get a USB device's path like /dev/ttyACM0 or /dev/ttyUSB0 according to its idVedor and idProduct? The subsequent function needs this path instead of its idVendor and idProduct.

Notice: by C/C++ code, not by Command.

I am using Qt and CentOS.

dtech
  • 47,916
  • 17
  • 112
  • 190
Jeff
  • 111
  • 2
  • 9

1 Answers1

1

You can use libusbp, a USB abstraction library, to do that. See the port_name example that comes with libusbp. This will definitely work for USB CDC ACM devices (e.g. /dev/ttyACM0) but I'm not sure if it will work for devices that use a different driver. If you try it, please post a comment here about whether it worked.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • Thanks David. I found another solution in the following link: http://stackoverflow.com/questions/14279796/linux-libusb-get-usb-device-path?rq=1. This solution is using libusb directly. I will try both of them. – Jeff Feb 24 '17 at 04:56
  • 1) libusb::libusb_get_port_path(), libusb 1.0.21. The result is not what I expected. It is not a string like /dev/ttyACM0. Instead, it is still similar with the result of libusb_get_port_numbers(). I didn't find more examples about how to use libusb_get_port_path() and how to parse its parameters. From http://libusbx.sourceforge.net/api-1.0/group__dev.html#ga9d392b8dff7abf5e475c72fd071c3c34, I found that libusb_get_port_path() is the depreciated version of libusb_get_port_numbers(). – Jeff Feb 27 '17 at 22:44
  • 2) libusbp::find_device_with_vid_pid(), libusbp 1.0.1 Since I am using qmake4.8.6 but libusbp requires c++11, I had to add `QMAKE_CXXFLAGS += -std=c++11` in the .pro file. But after that, another error came up: [main.o] Error 1. I checked Qt "Compile Output", and it said "cc1plus: error: unrecognized command line option "-std=c++11". – Jeff Feb 27 '17 at 22:45
  • I am using g++ 4.4.7, but at least g++ 4.7 supports c++11. It seems that I have to upgrade my g++. – Jeff Feb 27 '17 at 23:08
  • Your old version of GCC might support the `--std=c++0x` option which is almost as good. GCC 4.4.7 is pretty old, so upgrading would be a good idea. But please note that only the libusbp C++ wrapper requires C++11; libusbp itself is written in C and has a C API that you could probably use with old versions of GCC. Most of the examples are written in C++11 so it's handy to have a C++11 compiler so you don't have to translate the examples into C. – David Grayson Feb 28 '17 at 00:32
  • I have no enough access level to install software freely, so I have to use old GCC. I used C functions in "libusbp.h" instead of "libusbp.hpp". But when I compiled it, two link error came up: undefined reference to `udev_device_get_is_initialized` and `udev_enumerate_add_match_parent`. I didn't find any definition about them in src code. So I had to remove them in src code, and again cmake, make, make install. Now compiled it successfully! But the result said "error while loading shared libraries: libusbp-1.so.1.0.1: cannot open shared object file: No such file or directory". – Jeff Feb 28 '17 at 03:56
  • I found the solution. In .pro file, change `LIBS += /libpath/libusbp/lib/libusbp-1.so.1.0.1` to `LIBS += -L/libpath/libusbp/lib libusbp-1.so.1.0.1`. – Jeff Feb 28 '17 at 04:54
  • 1
    In my test program, interface_number has to be 0 or 1 instead of 2, and composite being true or false are both OK. Below is my test result: `/dev/ttyACM0`. – Jeff Feb 28 '17 at 04:57
  • In addition to changing LIBS, libusbp-1.so.1.0.1 should also be copied into the same directory with exe file. Otherwise, compile error would come up. – Jeff Feb 28 '17 at 05:08
  • Hi David, can you please check where the definitions of udev_device_get_is_initialized and udev_enumerate_add_match_parent? I guess in the current git repository, maybe some files are missing. – Jeff Feb 28 '17 at 22:34
  • Those functions come from libudev, one of the dependencies of libusbp on Linux, so this is not a case of missing files. The most likely explanation is that those functions were added to libudev in recent years and you are using an old version of that library. – David Grayson Mar 01 '17 at 00:22
  • What do you mean? What port name do they share and how did you determine this? – David Grayson Jun 08 '17 at 05:54
  • Now I have two devices, whose vendorID and productID are totally different, but get a same port name. Why? One device's driver is ftdi_sio, the other device's driver is cdc_acm. The port names I got soemtimes are both ttyUSB0, and sometimes are both ttyACM0. My linux is centos 2.6.32-696. – Jeff Jun 08 '17 at 05:56
  • Hi David, I can determine them using lsusb command. They are definitely different from the result of lsusb. But the port names I got by libusbp are same, either ttyACM0 or ttyUSB0, depending on which usb port I plugged them into. – Jeff Jun 08 '17 at 06:03
  • ttyACM0 is different from ttyUSB0 – David Grayson Jun 08 '17 at 06:14
  • Yes, ttyACM0 is different from ttyUSB0. But what I mean is they are either both ttyACM0, or both ttyUSB0. – Jeff Jun 08 '17 at 06:20