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.rules
to94-TI_launchpad.rules
Change
ATTR
toATTRS
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.
plugdev
if 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
. Useudevadm
to get an idea of the device chain, andstrace
to see which filemspdebug
actually wants to open before it errors out.ls -l /dev/ttyACM0 /dev/ttyACM1
?ACTION=="add",SUBSYSTEM=="tty",
and changeATTR
toATTRS
to check the parents. See writing_udev_rules. Also consider renumbering your file higher, as laterGROUP=
settings may override.