How to bind USB device under a static name? - Page 1
Forum section: electronics / general

author: Karel
author_rank: Super Contributor
timestamp: March 25, 2025, 03:15:15 pm
content: I want to bind a usb2 serial converter cable to a device file name other than /dev/ttyUSB0/1/2/3/4.It's ok if I could bind it to, for example, /dev/ttyUSB8 because I never use more than 5 converter cables at a time.To be clear, a solution as proposed here does not work for me because the converter cable will still occupy /dev/ttyUSB0.https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-nameI want to keep /dev/ttyUSB0 to 5 free for any converter cables that will be attached later.Is this possible?

author: eleguy
author_rank: Regular Contributor
timestamp: March 25, 2025, 03:47:40 pm
content: Quote from: Karel on March 25, 2025, 03:15:15 pmTypical issues are that the rules do not match the device or then some other rule catches it before your rule. These rules are (at least in debian) found in /etc/udev/rules.d/ folder and are processed in order. That is why the filenames do start with number.I would suggest you keep on trying with the udev rules. You should be able to create a link with a simple rule likeACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="yyyy", ATTRS{idProduct}=="xxxx", SYMLINK+="coolusbdevice"Replace yyyy and xxxx to match your device. You can find this info (for example) from the dmesg after plugging the device or using lsusb command.After creating a rule first reload the rules (udevadm control --reload-rules && udevadm trigger) then unplug and plug the device to see what happens. It is maybe good idea to debug stuff (in the way or other). For example commandudevadm monitorcan be handy.This is not the most comprehensive reply but hopefully you get started with the extra help of searching the net at-least.

author: Karel
author_rank: Super Contributor
timestamp: March 25, 2025, 04:58:56 pm
content: Quote from: eleguy on March 25, 2025, 03:47:40 pmI haven't tried it yet, but are you saying that /dev/ttyUSB0 will not be created when using the correct udev rule?Because I thought that the rule creates a symlink to /dev/USB0 which means that (if I understand correctly) /dev/ttyUSB0 will be present together with the symlink.

author: madires
author_rank: Super Contributor
timestamp: March 25, 2025, 05:29:24 pm
content: I guess it should be possible, but it would require some heavy lifting with a high probability in screwing things up. The best approach is, as eleguy already pointed out, to create symlinks bound to specific devices via custom udev rules.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 25, 2025, 07:52:25 pm
content: When using a symlink rule it's just adding a link to the original dev node, the original dev node remains.Try replacing theCode:SYMLINK += "xxxx"in the rule withCode:NAME = "xxx"and let me know if that does the trick.

author: madires
author_rank: Super Contributor
timestamp: March 25, 2025, 08:35:36 pm
content: Renaming works too, but will become messy if you connect multiple devices matching that rule, e.g. multiple PL2303 USB2serial adapters.

author: langwadt
author_rank: Super Contributor
timestamp: March 25, 2025, 09:01:52 pm
content: Quote from: SiliconWizard on March 25, 2025, 07:52:25 pmafaiu udev can no longer change the name only add symlinks, something about it being a security issue

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 25, 2025, 11:31:53 pm
content: Quote from: langwadt on March 25, 2025, 09:01:52 pmAh, looks like you're right. So, no go here.So, for the OP, rather than trying to absolutely "reserve" the ttyUSBxx names, the reasonable approach would probably be to add rules for other devices that also need a particular name. If the OP is using third-party apps that absolutely require dev names like ttyUSBxx with xx <= n, then, I feel sorry for them. :'( That would remind me of those old Windows apps that would absolutely require COMx serial port names with x <= 9 otherwise they would just not be able to use the port. And admittedly, many apps using virtual serial ports kept doing the same crap for a pretty long time, so if that's what the OP is running into but on Linux, well. That bites.

author: eleguy
author_rank: Regular Contributor
timestamp: March 26, 2025, 06:38:41 am
content: Maybe I did not catch your use case. Would you like to "point" to particular ttyUSBx as THE "same" device every time and that is why these programmers are pushed "further"? If so, wont work as these links are not "stable" meaning the order you push stuff in will change numbering (at least). But no worries what so ever. One can be very creative with these rules.With the commandudevadm info /dev/ttyUSB0you can figure out what all can be "matched" in the rules. Notice that stuff is capitalized in the output but we can use those "as-is". Here are some examplesa) vendor and model idCode:ENV{ID_VENDOR_ID}=="10c4", ENV{ID_MODEL_ID}=="ea60",SYMLINK+="serial_sensor"b) serial number of the device if you have many similar for example. Give another name here I used same. My cheap cp2102 converter dongles seemed to have same serial number over all so not that helpful always. Apparently one can change it with some tool xyz. So, maybe not that helpful if you have same situation there.Code:ENV{ID_VENDOR_ID}=="10c4", ENV{ID_MODEL_ID}=="ea60",ENV{ID_SERIAL_SHORT}=="0001",SYMLINK+="serial_sensor"c) Physical location of the device. For example you have usb hub with several ports. Now make a rule per port. Add a sticker on the usb hub and you know for sure (if not changing the hub's uplink cable anywhere) where particular port is always mapped.Code:ENV{ID_PATH}=="pci-0000:00:14.0-usb-0:10.4:1.0",SYMLINK+="serial_sensor"Certainly one can mix these as long they stay in the "sight" of the rule engine. In addition you can trigger what so ever with these rules. For example one could run a script by addingRUN+="/home/user/superscript.sh"which could send a message to homeassistant and ask it to turn room lights into "developer mode" when your serial converter is attached.

author: magic
author_rank: Super Contributor
timestamp: March 26, 2025, 09:16:39 am
content: Perhaps the "run a script" approach could work to rename ttyUSB0 to ttyUSB8?Or is it the kernel rather than udev which refuses to rename device files?

author: golden_labels
author_rank: Super Contributor
timestamp: March 26, 2025, 12:24:58 pm
content: BothNAMEandSYMLINKsupport variable substitution.(1)Among them the%sand%Esubstitutions.udev (7)(archived)

author: Nominal Animal
author_rank: Super Contributor
timestamp: March 26, 2025, 01:19:32 pm
content: Quote from: Karel on March 25, 2025, 03:15:15 pmI do that routinely, using names like/dev/ttyTeensy-serialnumber.For progamming native-USB developer boards under Arduino IDE, for example Pro Micro clones, I have wrapped AVRdude in my own script that scans for applicable devices, and if there is more than one, uses the IDE-selected one; otherwise the only one present. Then, it resets the device (using the zero-baudrate trick), waits for the board to disappear and appear under a new name (this happens because the USB stuff also gets reset –– again, these have native USB, not USB-serial translator ICs), and uses that new name ignoring the Arduino IDE selected port. This way, as long as I don't plug or unplug other USB devices while programming one of these, I don't need to hassle with the Arduino IDE port selection at all; stuff Just Works the way it should without any hassle. Teensies, of course, use the Teensy Loader application, so they don't need any of these shenanigans.Quote from: Karel on March 25, 2025, 03:15:15 pmExactlywhatwouldn't it work? I am asking because I want to understand the underlying requirements and limitations, and it sounds like you're well along some solution path that may have a much easier alternative one if you backtracked a bit on the choices you've already made.As an example, input event devices (keyboards, mice, joysticks, gamepads, touchpads, touchscreens, et cetera) are/dev/input/eventN, but also havestablenames under/dev/input/by-id/and/dev/input/by-path/. Treating the/dev/input/eventNnames as stable is the wrong approach, because they are not; they onlyappearso for built-in devices due to device driver probing order.Anyway, device symlinks and access modes are managed byudev. When a device insertion/removal event occurs, the kernel generates anueventto the currently runningudevdaemon, which creates and removes the device node under/dev. Theueventcontains the base device name, as set by the kernel driver in adev_set_name()call. For example, thettyUSBname comes from thedrivers/usb/serial/usb-serial.c:usb_serial_probe(); see the call.The kernel does not use the file name to associate the device with a kernel driver; the device type identifier in the POSIX inode data is used for this. See thest_rdevfield in file statistics (e.g.man 2 fstat), or usestat -c '%t:%T'filenameto see it for a specific device file.Because of this, "binding" a kernel-assigned device filename is not the right approach in Linux. We use the symlinks instead, either directly under/dev/or under a dedicated directory under/dev/, like/dev/input/by-id/or/dev/input/by-path/for input event devices.Quote from: Karel on March 25, 2025, 03:15:15 pmNot simply, nor robustly. Changing the device file name is possible, but will confuse udev, and possibly the generic USB Serial driver when plugging in new devices.A much better solution would be to create a symlink directory, for example/dev/serial/, which you populate using stable names for the USB serial devices you have. For example, the/etc/udev/rules.d/00-teensy.rulesI currently use isCode:# Disable ModemManager from probing Teensies to see if they are modems.ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", ENV{MTP_NO_PROBE}="1"# Use 'adm' group for Teensy serial ports, using symlink 'ttyTeensy-serial', with raw termios echo disabed.KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", GROUP:="adm", MODE:="0660", RUN:="/bin/stty -F /dev/%k raw -echo", SYMLINK+="ttyTeensy-$attr{serial}"# Use 'adm' group for Teensy HID devices.KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", GROUP:="adm", MODE:="0660"KERNEL=="hidraw*", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="013*", GROUP:="adm", MODE:="0660"# Use 'adm' group for Teensy bulk USB devices.SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04*", GROUP:="adm", MODE:="0660"SUBSYSTEMS=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="013*", GROUP:="adm", MODE:="0660"Thesttycommand is particularly useful, because that way, when I have a Teensy output stuff to ArduinoSerial, I only need tocat /dev/ttyTeensy-serialto see the output.The laptop I'm using (HP EliteBook 840 G4) is finally showing signs of konking out (CPU frequency issues, need to replace DC power socket), and I'm not sure what I'm going to use for a replacement, but I intend to switch to Linux Mint 22.1 (after refurbishing this one or getting a new laptop), and use the/dev/serial/for my device symlinks. Main reason is Tab interpolation: I then only need to type/dev/se, pressTab, then type the first characters of the name –– without anyttyprefixes, only serial and USB serial symlinks will be there, i.e. by default all are tty devices. As it is now, my symlinks tend to clash with standard device names under/dev/.

author: Karel
author_rank: Super Contributor
timestamp: March 29, 2025, 11:14:17 am
content: Thanks to everybody for trying to help and providing valuable info.During my experiments I discovered that my system (OpenSuse Leap) already creates something similar without the need to do anything.When I plugin a usb2serial converter cable, not only /dev/ttyUSBx will be created, but alsoCode:/dev/serial/by-id/usb-FTDI_US232R_FTGEBIKR-if00-port0that conveniently has the unique serial number in it.

author: voltsandjolts
author_rank: Unknown
timestamp: March 29, 2025, 12:57:58 pm
content: Ah, interesting, thanks Karel. Wasn't aware of this udev feature.https://superuser.com/questions/839667/how-is-by-id-created-on-linux

author: Karel
author_rank: Super Contributor
timestamp: March 29, 2025, 01:53:49 pm
content: Quote from: voltsandjolts on March 29, 2025, 12:57:58 pmMe neither, I accidently discovered it

author: madires
author_rank: Super Contributor
timestamp: March 29, 2025, 03:26:37 pm
content: Some devices don't come with a unique ID (lsusb -v):Code:iManufacturer 1 Prolific Technology Inc.iProduct 2 USB-Serial ControlleriSerial 0

author: Karel
author_rank: Super Contributor
timestamp: March 29, 2025, 04:17:43 pm
content: Quote from: madires on March 29, 2025, 03:26:37 pmIt's one of the reasons I insist on buying FTDI only for usb2serial converter chips and cables.You pay a bit more but they are the most robust and best supported.

author: SiliconWizard
author_rank: Super Contributor
timestamp: April 02, 2025, 06:26:55 pm
content: By "unique ID" you mean iSerial? The manufacturer is free to return whatever it likes for this, it's actually a "string" as per USB so that could be just letters or nothing at all. It's good practice to return something reasonably unique across all devices with the same VID and PID, but it's never guaranteed. But yes, you can use this "serial" thing in udev rules.FTDI does return a value that looks unique, although I don't know how much of a guarantee you have when using the value that's written in factory. For those FTDI chips that are customizable (internal or external EEPROM), note that you can write the serial string yourself if you ever want to modify it.

author: Karel
author_rank: Super Contributor
timestamp: April 03, 2025, 08:26:20 am
content: I have more than a dozen FTDI cables and they all have different serial numbers.At least for me it works (I use them in fixed test setups for biannual recurrent tests of our products).