14

In our Linux box we have USB -> serial device which was always identified as /dev/ttyACM0. So I've written an application and until yesterday, everything worked fine. But suddenly (yeah, during the remote presentation ...) the device stopped working. After quick research, I found that the connection changed to /dev/ttyACM1. It was a little untimely, but now I have a problem - how to unambiguously identify my device? Like, for example, the storage drive could be initialized using UUID although the /dev/sd** has changed. Is there some way to do that for serial devices?

Now I use a stupid workaround:

for(int i = 0; i < 10; i ++)
{
    m_port = std::string("/dev/ttyACM") + (char)('0' + i);
    m_fd = open(m_port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
}

The link to the device we use.

2 Answers 2

20

Since we are talking USB devices and assuming you have udev, you could setup some udev rules.

I guess, and this is just a wild guess, somebody or something unplugged/removed the device and plugged it back in/added the device again, which bumps up the number.

Now, first you need vendor and product id's:

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 011: ID 0403:6001 FTDI FT232 USB-Serial (UART) IC

Next, you need the serial number (in case you have several):

# udevadm info -a -n /dev/ttyUSB1 | grep '{serial}' | head -n1
    ATTRS{serial}=="A6008isP"

Now, lets create a udev rule:

UDEV rules are usually scattered into many files in /etc/udev/rules.d. Create a new file called 99-usb-serial.rules and put the following line in there, I have three devices, each with a a different serial number:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6008isP", SYMLINK+="MySerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A7004IXj", SYMLINK+="MyOtherSerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDIF46B", SYMLINK+="YetAnotherSerialDevice"

ls -l /dev/MySerialDevice
lrwxrwxrwx 1 root root 7 Nov 25 22:12 /dev/MySerialDevice -> ttyUSB1

If you do not want the serial number, any device from vendor with same chip will then get the same symlink, only one can be plugged in at any given time.

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="MySerialDevice"

Taken from here

4
  • 3
    If you have a recent linux distribution, most likely it already automatically creates the device as /dev/serial/by-id/usb-XXXX_USB2.0-Serial-if00-port0. This might be enough for you without custom udev rules.
    – Josef
    Mar 20, 2019 at 10:07
  • 1
    Unfortunately, many no-name devices all have the serial number "0123456789abcdef". That's where it gets interesting.
    – user313992
    Mar 20, 2019 at 11:03
  • @mosvy are serial numbers unchangable?
    – OganM
    Mar 20, 2019 at 20:05
  • @OganM they may be changed ... if you're able to root the devices.
    – user313992
    Mar 20, 2019 at 20:24
0

UDEV rules is good idea but many devices hasn't serial or has same serial and that does not solve the problem ttyACM0 to ttyACM1

Try

systemctl stop ModemManager systemctl disable ModemManager

P.S. I'm not a magician, I'm just learning, but friendship helps us do real miracles

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .