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:
Move the file from
46-TI_launchpad.rulesto94-TI_launchpad.rulesChange
ATTRtoATTRSin 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.
plugdevif you plug it in. The most likely error is that this is not the device file that's actually needed bymspdebug, but you need a different device atop that one. But that's impossible to say without seeing all important udev-rules, and runningmspdebug. Useudevadmto get an idea of the device chain, andstraceto see which filemspdebugactually wants to open before it errors out. – dirkt Jun 20 '20 at 15:43ls -l /dev/ttyACM0 /dev/ttyACM1? – Hauke Laging Jun 21 '20 at 03:31ACTION=="add",SUBSYSTEM=="tty",and changeATTRtoATTRSto check the parents. See writing_udev_rules. Also consider renumbering your file higher, as laterGROUP=settings may override. – meuh Jun 21 '20 at 08:35