Mapping FTDI to files with udev

In the course of making a to-be-revealed robot, I’ve encountered problems with various FTDI cables (and their attached peripherals) being automatically mounted in different locations, depending on the order in which they were inserted and initialized. For obvious reasons, this poses an issue – the IMU cable won’t work well with motor commands, and the actuator controller doesn’t give any IMU data.

After some thinking, I decided to solve the problem via udev mounting (somewhat hackish). In Linux, udev controls the mounting of various hardware peripherals to mountpoints in the file system. This tutorial is written for Ubuntu 10.10, but could easily be translated to any distribution of Linux (and probably Mac OS X, as well).

Step 1: Plug in your FTDI device (this will be an FTDI breakout of some sort, or perhaps an Arduino Duemilanove or older)

Step 2: Find its current mountpoint: Ubuntu mounts FTDI devices to /dev/ttyUSB*, where * is a number.
In the terminal, type this:

ls /dev/ttyUSB*

Output:

$ ls /dev/ttyUSB*
/dev/ttyUSB0
/dev/ttyUSB1

I’m going to assume that we’re working with /dev/ttyUSB0 for the rest of this post.

Step 3: Find the udev properties that are unique to each FTDI device.
In the terminal, type this:

$ udevadm info -a -p $(udevadm info -q path -n ttyUSB0) | egrep -i "ATTRS{serial}|ATTRS{idVendor}|ATTRS{idProduct}" -m 3

I recognize that the regex used in the egrep isn’t the most concise, but it works (anyone want to suggest something better?).
The output will look something like this:

$ udevadm info -a -p $(udevadm info -q path -n ttyUSB0) | egrep -i "ATTRS{serial}|ATTRS{idVendor}|ATTRS{idProduct}" -m 3
ATTRS{idVendor}=="0403"
ATTRS{idProduct}=="6001"
ATTRS{serial}=="A700eEPB"

Record all the values in the quotes – you’ll need them in the next steps.

Step 4: Create the udev file.
In the terminal, create a file named 10-ftdi.rules in /etc/udev/rules.d with 644 permissions.
$ sudo touch /etc/udev/rules.d/10-ftdi.rules && sudo chmod 644 /etc/udev/rules.d/10-ftdi.rules
Open the file with your favorite text editor:

$ sudo vim /etc/udev/rules.d/10-ftdi.rules

and copy this line in:

BUS=="usb", SYSFS{idProduct}=="IDPRODUCT", SYSFS{idVendor}=="IDVENDOR", SYSFS{serial}=="SERIAL", NAME="DEVICENAME"

Substitute your values from Step 3 for IDPRODUCT, IDVENDOR, and SERIAL. DEVICENAME will be your new mountpoint.
Save and close the file.

Step 5: Remove your FTDI cable and plug it back in (this will remount it using your new rule). It should now be mounted in /dev/DEVICENAME, where DEVICENAME is what you put in the NAME field in the udev rule.

Step 6: Repeat this process for your other FTDI devices. Consecutive udev rules can be placed on the next line in the same file – no need to create another one.

This quick and easy trick lets you assign memorable mountpoints to otherwise identical devices – a godsend when you’ve got a few too many to work with.

7 Responses to “Mapping FTDI to files with udev”

  1. Andrew Dahlin

    Super useful post, thanks!

    Things have changed a bit in ubuntu (on 12.04 at least). The rule should look something like the following:
    SUBSYSTEM==”usb”, ATTRS{idProduct}==”IDPRODUCT”, ATTRS{idVendor}==”IDVENDOR”, ATTRS{serial}==”SERIAL”, NAME=”DEVICENAME”

    I couldn’t get this to work, but I think it’s closer at least.. hopefully someone can pick up the ball and get it working. I’ll put a bit more effort in this time allowing.

    Also a couple useful debugging things:
    sudo udevadm test /dev/bus/usb/ will output useful debugging info (and a lot of not useful info. In my case, it let me know the rules I made was invalid and why. (There’s probably a better what to do this, but it works!)

    Reply
  2. devzero

    Sorry, a little late but just to complete it here:

    It is SUBSYSTEMS (with s!)

    Reply
  3. fidolo

    Thanks a gazillion!
    The updated code (by Andrew, and corrected by devzero) works well for me on Mint-14 64-bit.

    Reply
  4. “Mapping FTDI to files with udev | Aeturnalus” was indeed
    a superb post and thus I was in fact pretty joyful to
    find it. Thanks for your time,Mandy

    Reply
  5. Miles Bintz

    On x86 Linux Mint, udev was not creating devices as suggested above. If you match on SUBSYSTEM usb and the FTDI serial number you can get a symlink to the USB endpoint but not the TTY device. If you match on SUBSYSTEM tty then the FTDI serial number isn’t in ATTRS{serial}.

    Doing a udevadm info -e /dev/ttyUSB0 helps shed light on useful variables that you can act on in your rule. This is what ended up working for me:

    SUBSYSTEM==”tty”, ENV{ID_SERIAL_SHORT}==”AH02VGKA”, SYMLINK+=”ttySIMA”

    Reply

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>