0

I'm using the mspdebug programmer to connect to a device.

mspdebug will only connect to the device when I use sudo mspdebug. If I don't use sudo, mspdebug can't find the device.

How can I connect to the device without needing sudo?

The device in particular I want to connect to is listed here:

$ lsusb
Bus 001 Device 018: ID 2047:0013 Texas Instruments MSP Tools Driver

I have these udev rules in /etc/udev/rules.d/46-TI_launchpad.rules:

ATTR{idVendor}=="0451", ATTR{idProduct}=="f432", MODE="0660", GROUP="plugdev"
ATTR{idVendor}=="2047", ATTR{idProduct}=="0013", MODE="0660", GROUP="plugdev"

I am in the plugdev group:

$ id $USER
uid=1000(earthishome) gid=1000(earthishome) groups=1000(earthishome),10(wheel),977(pkg-build),1001(plugdev),974(vboxusers),1003(docker)

Edit 1

Tracking down the device

When plugging in the device, two ttys are created: ttyACM0 and ttyACM1:

$ udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[21580.524390] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2 (usb)
KERNEL[21580.527712] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0 (usb)
KERNEL[21580.528138] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/tty/ttyACM0 (tty)
KERNEL[21580.528301] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0 (usb)
KERNEL[21580.528453] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.1 (usb)
KERNEL[21580.528623] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.1 (usb)
KERNEL[21580.528892] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2 (usb)
KERNEL[21580.529451] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2/tty/ttyACM1 (tty)
KERNEL[21580.529600] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2 (usb)
KERNEL[21580.529746] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.3 (usb)
KERNEL[21580.529892] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.3 (usb)
KERNEL[21580.530075] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2 (usb)
UDEV  [21580.563378] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2 (usb)
UDEV  [21580.570495] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0 (usb)
UDEV  [21580.572104] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.1 (usb)
UDEV  [21580.573582] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.3 (usb)
UDEV  [21580.573663] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2 (usb)
UDEV  [21580.577042] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.1 (usb)
UDEV  [21580.578987] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.3 (usb)
UDEV  [21580.579357] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/tty/ttyACM0 (tty)
UDEV  [21580.580712] add      /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2/tty/ttyACM1 (tty)
UDEV  [21580.585516] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0 (usb)
UDEV  [21580.585592] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.2 (usb)
UDEV  [21580.596329] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-2 (usb)

Using strace

There is a "permission denied" error when trying to open /dev/ttyACM0 that doesn't happen when I run strace sudo mspdebug tilib.

$ strace mspdebug tilib
openat(AT_FDCWD, "/dev/ttyACM0", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 EACCES (Permission denied)
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=5000000}, NULL) = 0
openat(AT_FDCWD, "/dev/ttyACM0", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 EACCES (Permission denied)
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=5000000}, NULL) = 0
openat(AT_FDCWD, "/dev/ttyACM0", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 EACCES (Permission denied)
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=5000000}, NULL) = 0
openat(AT_FDCWD, "/dev/ttyACM0", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 EACCES (Permission denied)
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=5000000}, NULL) = 0

Using udevadm to find the device and its parents

$ udevadm info --attribute-walk /dev/ttyACM0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/tty/ttyACM0':
    KERNEL=="ttyACM0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0':
    KERNELS=="1-2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="cdc_acm"
    ATTRS{iad_bFunctionSubClass}=="02"
    ATTRS{bmCapabilities}=="2"
    ATTRS{interface}=="MSP Debug Interface"
    ATTRS{bInterfaceClass}=="02"
    ATTRS{authorized}=="1"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{iad_bFunctionClass}=="02"
    ATTRS{iad_bFunctionProtocol}=="01"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{iad_bFirstInterface}=="00"
    ATTRS{bInterfaceSubClass}=="02"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{iad_bInterfaceCount}=="02"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-2':
    KERNELS=="1-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{busnum}=="1"
    ATTRS{authorized}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{devnum}=="14"
    ATTRS{bmAttributes}=="80"
    ATTRS{rx_lanes}=="1"
    ATTRS{serial}=="B1443A5106001800"
    ATTRS{bcdDevice}=="0200"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{product}=="MSP Tools Driver"
    ATTRS{idVendor}=="2047"
    ATTRS{bDeviceSubClass}=="02"
    ATTRS{speed}=="12"
    ATTRS{removable}=="removable"
    ATTRS{urbnum}=="140"
    ATTRS{devpath}=="2"
    ATTRS{bDeviceClass}=="ef"
    ATTRS{bNumInterfaces}==" 4"
    ATTRS{tx_lanes}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{idProduct}=="0013"
    ATTRS{configuration}=="MSP430 USB"
    ATTRS{maxchild}=="0"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{quirks}=="0x0"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{manufacturer}=="Texas Instruments"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{bConfigurationValue}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized_default}=="1"
    ATTRS{idVendor}=="1d6b"
    ATTRS{speed}=="480"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{ltm_capable}=="no"
    ATTRS{version}==" 2.00"
    ATTRS{rx_lanes}=="1"
    ATTRS{busnum}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{urbnum}=="268"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bcdDevice}=="0506"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{configuration}==""
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{quirks}=="0x0"
    ATTRS{manufacturer}=="Linux 5.6.19-300.fc32.x86_64 xhci-hcd"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{idProduct}=="0002"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{authorized}=="1"
    ATTRS{maxchild}=="12"
    ATTRS{removable}=="unknown"
    ATTRS{tx_lanes}=="1"
    ATTRS{product}=="xHCI Host Controller"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{device}=="0x9d2f"
    ATTRS{dbc}=="disabled"
    ATTRS{irq}=="126"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{subsystem_device}=="0x082a"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{class}=="0x0c0330"
    ATTRS{subsystem_vendor}=="0x1028"
    ATTRS{vendor}=="0x8086"
    ATTRS{enable}=="1"
    ATTRS{local_cpulist}=="0-7"
    ATTRS{ari_enabled}=="0"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{revision}=="0x21"
    ATTRS{broken_parity_status}=="0"
    ATTRS{local_cpus}=="ff"
    ATTRS{msi_bus}=="1"
    ATTRS{numa_node}=="-1"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Edit 2

I was able to solve this thanks to the troubleshooting tips in the comments.

TLDR

There were two things that needed to change:

  1. Move the file from 46-TI_launchpad.rules to 94-TI_launchpad.rules

  2. Change ATTR to ATTRS in the rule as shown:

    ATTRS{idVendor}=="2047", ATTRS{idProduct}=="0013", MODE="0660", GROUP="plugdev"

Details

As both Artem S. Tashkinov and meuh pointed out, the rule was being overwritten by later rules. Renaming the file in the 90s ensures it'll run towards the end and not be overwritten by earlier rules.

Using udevadm info -a, as dirkt suggested, prints the whole device chain. Looking at the device chain, the actual device itself doesn't have the attributes idVendor and idProduct defined; these attributes are defined in the parent device. In order to match those attributes, ATTR must be changed to ATTRS to match attributes in parent devices.

4
  • 2
    Please check this question: unix.stackexchange.com/questions/200194/… – Artem S. Tashkinov Jun 20 '20 at 15:30
  • 1
    Debugging udev-rules is a bit of a PITA. First check which device file is created with group plugdev if you plug it in. The most likely error is that this is not the device file that's actually needed by mspdebug, but you need a different device atop that one. But that's impossible to say without seeing all important udev-rules, and running mspdebug. Use udevadm to get an idea of the device chain, and strace to see which file mspdebug actually wants to open before it errors out. – dirkt Jun 20 '20 at 15:43
  • What is the output of ls -l /dev/ttyACM0 /dev/ttyACM1? – Hauke Laging Jun 21 '20 at 3:31
  • 2
    Start with ACTION=="add",SUBSYSTEM=="tty", and change ATTR to ATTRS to check the parents. See writing_udev_rules. Also consider renumbering your file higher, as later GROUP= settings may override. – meuh Jun 21 '20 at 8:35
1

I was able to solve this thanks to the troubleshooting tips in the comments of the question.

TLDR

There were two things that needed to change:

  1. Move the file from 46-TI_launchpad.rules to 94-TI_launchpad.rules
  2. Change ATTR to ATTRS in the rule as shown:
ATTRS{idVendor}=="2047", ATTRS{idProduct}=="0013", MODE="0660", GROUP="plugdev"

Details

As both Artem S. Tashkinov and meuh pointed out, the 46 rule was being overwritten by later rules. Renaming the file in the 90s ensures it'll run towards the end and not be overwritten by earlier rules.

Using udevadm info -a, as dirkt suggested, prints the whole device chain. Looking at the device chain, the actual device itself doesn't have the attributes idVendor and idProduct defined; these attributes are defined in the parent device. In order to match attributes in parent devices, ATTR must be changed to ATTRS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.