5

I want to dedicate certain USB ports to certain devices. How can I do that?

For example: I want ttyUSB0 to be my mouse and ttyUSB1 to be my keyboard (always). I want to be certain that the startup of Linux never swaps them.

Acctually the thing is that I have XBee who usally goes to USB0 and a second FTDI that goes to USB1, for security reason I always want them to have the same address in my code I'm running.

Kind regards

2
  • 1
    Are you sure this is linux? In linux ttyUSBx are devices for USB serial terminals. Mouse & keyboard are HID-devices, watch for them in /dev/input.
    – Eddy_Em
    Jan 15, 2013 at 11:36
  • How could I possibly be mistaken of what OS I'm running? This is Debian on a Raspberry Pi.
    – Christian
    Jan 17, 2013 at 8:51

2 Answers 2

9

The kernel-assigned names are always assigned in the order the devices are detected, and you cannot change them. (Not anymore, anyway – this function was removed due to various race conditions that "persistent name" rules caused.)

But you can tell udev to create symlinks with whatever names you choose. In fact, on modern systems, you should already have symlinks under /dev/serial named after both the device's path, and its unique ID; for example:

  • /dev/serial/by-path/pci-0000:00:1a.0-usb-0:1.2:1.0ttyUSB0

  • /dev/serial/by-id/usb-Motorola_Inc._Motorola_Phone__C350_-if00ttyACM0

  • /dev/disk/by-id/ata-ST9640320AS_5WX1ZH91-part1sda1

  • /dev/disk/by-partlabel/Archsda3

  • /dev/input/by-id/usb-PIXART_USB_OPTICAL_MOUSE-mousemouse1

And so on. Just run tree /dev or ls -lR /dev to find your device.

You can also run udevadm info /dev/ttyUSB0 and all symlinks to that device will be listed as S: ... lines.


If this is not enough, you can write your own udev rules. First run udevadm info /dev/ttyUSB0 and choose any identifying property (such as ID_PATH for the USB port). It's a good idea to always include the subsystem as well.

Then open (or create) a file in /etc/udev/rules.d/ (named, for example, serial-symlinks.rules), and put the udev rule there.

For example, if the output for ttyUSB0 is:

$ udevadm info /dev/ttyUSB0
. . .
E: ID_PATH=pci-0000:00:1d.0-usb-0:1.2:1.0
. . .
E: SUBSYSTEM=tty
. . .

...you can write this rule:

SUBSYSTEM=="tty", ENV{ID_PATH}=="pci-0000:00:1d.0-usb-0:1.2:1.0", SYMLINK+="tty-xbee"

...and udev will always symlink /dev/tty-xbee to whatever tty device you connected to USB port #2.


(Note: Do not use the same names for symlinks as the kernel uses for device nodes. Using SYMLINK+="ttyUSB0" will cause bad things to happen.)

4
  • Excellent post! Thanks. Some time when I stop my code I note that XBee will change port from USB0 to USB1. I don't know the cause of this, but if I in my code instead of using path /dev/ttyUSB0 uses for example /dev/serial/by-id/usb-Motorola_Inc._Motorola_Phone__C350_-if00 this problem will be solved, right?
    – Christian
    Jan 17, 2013 at 9:00
  • @Christian: Yes. Jan 17, 2013 at 14:44
  • @grawity are the pci and usb port IDs under ` /dev/serial/by-path/` allocated according to the physical topology or according to a random (for any reason like parallel discovery) discovery order? Feb 12, 2016 at 10:01
  • @JulioGuerra: They're supposed to represent physical topology (that's pretty much the whole point of by-path over raw sequential tty* names). Note how the pci tag is followed by PCI domain:bus:slot.func, for example. /// That said, the physical topology can change too, if the firmware decides so – I've heard of a few PCs where the same physical PCI slot would get a different ID depending on whether other slots were filled... If that's also a concern, use by-id names. Feb 12, 2016 at 11:22
0

Here is what I do with USB serial devices:

  1. cd /dev/serial/by-id
  2. ls -l

    For example:

    root@toaster:/dev/serial/by-id# ls -l

    total 0
    lrwxrwxrwx 1 root root 13 Jan 1 1970 usb-FTDI_FT232R_USB_UART_A7035K2R-if00-port0 -> ../../ttyUSB0

  3. Make a symlink from this L-O-N-G name to a name of your choosing in a directory of your choosing. In my case, it is a system device and only root controls it so I make a link in /root, like:

    ln -s /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A7035K2R-if00-port0 /root/easydigi
    
  4. In your programs or whatever needs the device name of the serial device, you just use your link, in my case above "/root/easydigi", as the replacement for the "/dev/ttyUSB0".

0

You must log in to answer this question.

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