3
votes

I'm working with a USB device in Linux and have written a library to control this device.

Without going in to TOO many details, the device uses a standard UART protocol, so all I have to do is open a serial connection with open, configure the relevant parameters like baud rate, stop bit, parity, etc, etc, and start bit-banging registers.

The library works fine, however, it its hard coded to assume that this device is /dev/ttyUSB0. That is, this is what I pass to open. If open fails, I exit.

What I would like to do is detect that this device is present, regardless if it's /dev/ttyUSB0, /dev/ttyUSB1, etc. And even detect if there are multiple of these devices connected.

I can write code to poll certain registers on the device that will return serial number, product ID, etc, so I can detect that what is on the other end of the USB is indeed my device... but how can I find a list of connected USB devices, again, in native C?

OR is there a more elegant way of doing this, such as interfacing with it's kernel module, or something? I can provide the USB driver it actually uses, but I'm sort of lost when looking through the code.

Thanks for any insight.

2
I know of a Linux command--->lsusb-It's coding will give you some idea!!!Am_I_Helpful
While I don't readily have an answer to you, it's worth noting that Apple and Spotify use daemons to detect the connection of a media device.user559633
In a higher level application I will be running a separate thread to keep track of this by calling a function in my library. I'm just not sure how to implement this in my library.justynnuff
Check whether this is of any help to you--->github.com/gregkh/usbutils/blob/master/lsusb.cAm_I_Helpful
@shekharsuman I think this might insight into what I need! I'm very familiar with this command too, I didn't even think to look through its source code :|justynnuff

2 Answers

2
votes

The elegant method is to use udev to create a descriptive symlink for your device when it is connected. Add a line something like this to /etc/udev/rules.d

SUBSYSTEM=="tty",ENV{ID_MODEL}=="My_FlowMeter_Model",ENV{ID_USB_INTERFACE_NUM}=="00",SYMLINK+="flowmeter",RUN+="/bin/su pi -c /home/pi/record-flowmeter.sh

That's a very slightly modified version of an actual udev rule my research group uses to collect data from USB devices connected to battery-powered Raspberry Pi boxes. It also runs a script automatically, which has commands like

stty -F /dev/flowmeter 500000 -ixon -echo -icanon

If you want to know the "real" device filename, you could do readlink /dev/flowmeter. But for most uses you can just use the link: fd = open("/dev/flowmeter"); (or pass it as an argument to your program)

Naturally you should replace flowmeter with a short name for your own device, as well as updating the ID_MODEL based on the output from lsusb.

Multiple devices are a bit more complicated, but there are plenty of examples of udev rules out there.

1
votes

On Linux, the information you are looking for is in the /sys filesystem, specifically under /sys/bus/usb/devices. From there you will need to search the filesystem to find your device.

For example, I just plugged a USB-serial dongle into my Linux (kernel version 2.6.35) and the device appeared under /sys/bus/usb/devices/2.1-8. Here, I am able to find that this is my device by vendorId:deviceId by checking the files idVendor and idProduct. Here, there is a directory named 2.1-8:1:0 which contains a directory named ttyUSB0.

Obviously, to find your device you will need code (or a shell script using find) to scan the directory tree, looking for the right entries.