6
votes

I need to detect when a USB serial device is plugged or unplugged on my embedded system and know what is the tty associated with it.

My system runs over a 2.6 Linux Kernel.

Since I don't have write access to udev rules, nowadays I'm trying to get this information from the file system, looking for modifications in /sys/bus/usb/devices directory. However, I'm facing some problems with this approach.

I know what is the Id BUS of the USB port connected (e.g 1-1.3). So, I search for the associated tty (looking for a directory in /sys/bus/usb/devices/<Id BUS>:1.0/tty/ - e.g. /sys/bus/usb/devices/1-1.3:1.0/tty/ttyACM0). This way I know that I should use /dev/ttyACM0 to communicate with my device. But, sometimes, this device (/dev/ttyACM0) does not exist.

Is there any better way to get this information?

I even thought trying to get this information from the syslog, but I don't know whether this is a pretty good idea.

Edit:

Only to clarify, my system needs to be able to detect state changes in the USB bus, i.e. detecting when a new device is plugged (and getting the tty name linked to it) or an existing one is unplugged.

The system is monitoring up to N USB/serial devices, which are plugged to it using an USB HUB. During its normal execution new devices can be plugged, existing devices can be removed (or rebooted by a remote command - out of this scope). When a device is rebooted, it could receive a different tty from the previous one used before (e.g. ttyACM0 -> ttyACM3), since the kernel designates to it a tty which is free at the moment, and it is a big problem to me.

3

3 Answers

1
votes

Netlink is the preferred mechanism for communication between kernel and userspace.

You would create a Netlink socket with family NETLINK_KOBJECT_UEVENT, listen on that socket and filter out messages that contain SUBSYSTEM=usb and ACTION=add for USB plug events or ACTION=remove for USB unplug events.

0
votes

I wrote a USB abstraction library called libusbp. You should look at its port_name example, which shows how to use libusbp to get the serial port name (e.g. /dev/ttyACM0) for a USB serial device. Behind the scenes, libusbp gets this information using libudev.

0
votes

Check if the virtual file is deleted using stat.

#include <sys/statvfs.h>

...

struct stat sb;
return (stat("/dev/ttyUSB0", &sb) == 0); // true if open, false otherwise