Giving serial devices meaningful names

    This is a hack I've been using for ages, but I thought it deserved a write up.

    I have USB serial devices. Lots of them. I use them for home automation things, as well as for talking to devices such as the console ports on switches and so forth. For the permanently installed serial devices one of the challenges is having them show up in predictable places so that the scripts which know how to drive each device are talking in the right place.

    For the trivial case, this is pretty easy with udev:

    $  cat /etc/udev/rules.d/60-local.rules 
    KERNEL=="ttyUSB*", \
        ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
        ATTRS{serial}=="A8003Ye7", \
        SYMLINK+="radish"
    


    This says for any USB serial device that is discovered (either inserted post boot, or at boot), if the USB vendor and product ID match the relevant values, to symlink the device to "/dev/radish".

    You find out the vendor and product ID from lsusb like this:

    $ lsusb
    Bus 003 Device 003: ID 0624:0201 Avocent Corp. 
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 007 Device 002: ID 0665:5161 Cypress Semiconductor USB to Serial
    Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 004 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
    Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 009 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    


    You can play with inserting and removing the device to determine which of these entries is the device you care about.

    So that's great, until you have more than one device with the same USB serial vendor and product id. Then things are a bit more... difficult.

    It turns out that you can have udev execute a command on device insert to help you determine what symlink to create. So for example, I have this entry in the rules on one of my machines:

    KERNEL=="ttyUSB*", \
        ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", \
        PROGRAM="/usr/bin/usbtest /dev/%k", \
        SYMLINK+="%c"
    


    This results in /usr/bin/usbtest being run with the path of the device file on its command line for every device detection (of a matching device). The stdout of that program is then used as the name of a symlink in /dev.

    So, that script attempts to talk to the device and determine what it is -- in my case either a currentcost or a solar panel inverter.

    Tags for this post: linux udev serial usb usbserial
    Related posts: SMART and USB storage; Video4Linux, ov511, and RGB24 palettes; ov511 hackery; Ubuntu, Dapper Drake, and that difficult Dell e310; Roomba serial cables; Via M10000, video, and a Belkin wireless USB thing

posted at: 12:04 | path: /linux | permanent link to this entry