pyocd / pyOCD

Open source Python library for programming and debugging Arm Cortex-M microcontrollers
https://pyocd.io
Apache License 2.0
1.12k stars 478 forks source link

pyOCD fails to find connected DAPLink probe #1497

Closed cstrahan closed 1 year ago

cstrahan commented 1 year ago

pyOCD fails to find connected MCU-LINK flashed with latest DAPLink (CMSIS-DAP firmware):

$ pyocd list
No available debug probes are connected

This is with pyOCD installed from the latest tip of the develop branch.

While openocd and probe-rs-cli are able to detect the probe:

$ probe-rs-cli list
The following devices were found:
[0]: DAPLink CMSIS-DAP (VID: 0d28, PID: 0204, Serial: 000000808bb7918e5d0379760db6608a0f9f6b9e4c504355, CmsisDap)
cstrahan commented 1 year ago

From lsusb:

                |__ Port 3: Dev 110, If 3, Class=Vendor Specific Class, Driver=, 480M
                    ID 0d28:0204 NXP ARM mbed
                    /sys/bus/usb/devices/3-2.4.3.3  /dev/bus/usb/003/110
                |__ Port 3: Dev 110, If 1, Class=CDC Data, Driver=cdc_acm, 480M
                    ID 0d28:0204 NXP ARM mbed
                    /sys/bus/usb/devices/3-2.4.3.3  /dev/bus/usb/003/110
                |__ Port 3: Dev 110, If 4, Class=Vendor Specific Class, Driver=, 480M
                    ID 0d28:0204 NXP ARM mbed
                    /sys/bus/usb/devices/3-2.4.3.3  /dev/bus/usb/003/110
                |__ Port 3: Dev 110, If 2, Class=Human Interface Device, Driver=usbhid, 480M
                    ID 0d28:0204 NXP ARM mbed
                    /sys/bus/usb/devices/3-2.4.3.3  /dev/bus/usb/003/110
                |__ Port 3: Dev 110, If 0, Class=Communications, Driver=cdc_acm, 480M
                    ID 0d28:0204 NXP ARM mbed
                    /sys/bus/usb/devices/3-2.4.3.3  /dev/bus/usb/003/110
cstrahan commented 1 year ago

I just attached a debugger and started stepping through pyOCD. Realized there's a debug message that isn't printed by default (will see if I can figure out how to increase the log level):

ValueError('The device has no langid (permission issue, no string descriptors supported or device error)')

At this line

https://github.com/pyocd/pyOCD/blob/1e0bb1dc02f6d1f1726c5fcd949dd08725566d63/pyocd/probe/pydapaccess/interface/pyusb_backend.py#L375

cstrahan commented 1 year ago

If I override the usb backend with PYOCD_USB_BACKEND=hidapiusb and use CMSIS-DAP v1 interface (required because v2 implies that PYOCD_USB_BACKEND env var is ignored) with -Ocmsis_dap.prefer_v1=true, then it discovers my probe:

$ PYOCD_USB_BACKEND=hidapiusb pyocd list -Ocmsis_dap.prefer_v1=true
  #   Probe/Board     Unique ID                          Target  
-----------------------------------------------------------------
  0   0x0d28 0x0204   4QWS7RTU2NZB3FV5TNWNS3X46LQK2FKC   n/a     

It seems that pyusb (or the user thereof) is broken somehow.

cstrahan commented 1 year ago

It fails on this line:

https://github.com/pyocd/pyOCD/blob/1e0bb1dc02f6d1f1726c5fcd949dd08725566d63/pyocd/probe/pydapaccess/interface/pyusb_backend.py#L348

If I step into it, I arrive at this code in pyusb:

    if langid is None:
        langids = dev.langids
        if 0 == len(langids):
            raise ValueError("The device has no langid"
                             " (permission issue, no string descriptors supported or device error)")
        langid = langids[0]

As far as pyusb is concerned, this device reports no langids. This is odd to me, as probe-rs has no problem getting the product id.

Clearly pyusb can give the product string, because at some point in the pyOCD loop I come across my keyboard and such, and those give back product names just fine.

cstrahan commented 1 year ago

Wow. It just started randomly working -- haven't changed anything:

$ pyocd list
  #   Probe/Board             Unique ID                                          Target  
-----------------------------------------------------------------------------------------
  0   Arm DAPLink CMSIS-DAP   000000808bb7918e5d0379760db6608a0f9f6b9e4c504355   n/a     

Before, pyusb was failing somewhere here:

    @property
    def langids(self):
        """ Return the USB device's supported language ID codes.

        These are 16-bit codes familiar to Windows developers, where for
        example instead of en-US you say 0x0409. USB_LANGIDS.pdf on the usb.org
        developer site for more info. String requests using a LANGID not
        in this array should not be sent to the device.

        This property will cause some USB traffic the first time it is accessed
        and cache the resulting value for future use.
        """
        if self._langids is None:
            try:
                self._langids = util.get_langids(self)
            except USBError:
                self._langids = ()
        return self._langids

and it swallows any exceptions and acts as if the device reported no langids, which is a lie. Subsequently, dev.product fails because it raises ValueError if no explicit langid kwarg was given nor any langids (supposedly) reported by device (though, as noted earlier, this is a lie).

Dunno why openocd and probe-rs would work while pyocd would fail, but... here we are. For now, gonna chalk that up to computers being a pile of horrible, non-deterministic hacks that we call "specifications".

cstrahan commented 1 year ago

And it's happening again.

$ lsusb -vd '0d28:0204'

Bus 003 Device 094: ID 0d28:0204 NXP ARM mbed
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0d28 NXP
  idProduct          0x0204 ARM mbed
  bcdDevice           10.00
  iManufacturer           1 Arm
  iProduct                2 DAPLink CMSIS-DAP
  iSerial                 3 000000808bb7918e5d0379760db6608a0f9f6b9e4c504355
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x008b
    bNumInterfaces          5
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               4 (error)
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              4 (error)
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x03
          call management
          use DataInterface
        bDataInterface          2
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              5 (error)
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              6 (error)
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
          Report Descriptor: (length is -1)
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      3 
      bInterfaceProtocol      0 
      iInterface              7 (error)
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              9 (error)
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
cannot read device status, Resource temporarily unavailable (11)
cstrahan commented 1 year ago

I rebooted and now it looks like:

Bus 003 Device 015: ID 0d28:0204 NXP ARM mbed
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0d28 NXP
  idProduct          0x0204 ARM mbed
  bcdDevice           10.00
  iManufacturer           1 Arm
  iProduct                2 DAPLink CMSIS-DAP
  iSerial                 3 000000808bb7918e5d0379760db6608a0f9f6b9e4c504355
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x008b
    bNumInterfaces          5
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               4 mbed Serial Port
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              4 mbed Serial Port
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x03
          call management
          use DataInterface
        bDataInterface          2
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              5 mbed Serial Port
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              6 CMSIS-DAP v1
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      3 
      bInterfaceProtocol      0 
      iInterface              7 WebUSB: CMSIS-DAP
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              9 (error)
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
cannot read device status, Resource temporarily unavailable (11)
cstrahan commented 1 year ago

And on yet another run (after re-plugging in), all of the (errors) are gone:

Bus 003 Device 030: ID 0d28:0204 NXP ARM mbed
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0d28 NXP
  idProduct          0x0204 ARM mbed
  bcdDevice           10.00
  iManufacturer           1 Arm
  iProduct                2 DAPLink CMSIS-DAP
  iSerial                 3 000000808bb7918e5d0379760db6608a0f9f6b9e4c504355
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x008b
    bNumInterfaces          5
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass       2 Abstract (modem)
      bFunctionProtocol       1 AT-commands (v.25ter)
      iFunction               4 mbed Serial Port
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              4 mbed Serial Port
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x03
          call management
          use DataInterface
        bDataInterface          2
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              5 mbed Serial Port
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              6 CMSIS-DAP v1
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      3 
      bInterfaceProtocol      0 
      iInterface              7 WebUSB: CMSIS-DAP
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              9 CMSIS-DAP v2
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Binary Object Store Descriptor:
  bLength                 5
  bDescriptorType        15
  wTotalLength       0x0039
  bNumDeviceCaps          2
  Platform Device Capability:
    bLength                24
    bDescriptorType        16
    bDevCapabilityType      5
    bReserved               0
    PlatformCapabilityUUID    {3408b638-09a9-47a0-8bfd-a0768815b665}
      WebUSB:
        bcdVersion    1.00
        bVendorCode     33
        iLandingPage     0 
  Platform Device Capability:
    bLength                28
    bDescriptorType        16
    bDevCapabilityType      5
    bReserved               0
    PlatformCapabilityUUID    {d8dd60df-4589-4cc7-9cd2-659d9e648a9f}
    CapabilityData[0]    0x00
    CapabilityData[1]    0x00
    CapabilityData[2]    0x03
    CapabilityData[3]    0x06
    CapabilityData[4]    0x4a
    CapabilityData[5]    0x01
    CapabilityData[6]    0x20
    CapabilityData[7]    0x00
Device Status:     0x0000
  (Bus Powered)

If I run lsusb rapidly several times, the errors show up again and persist until I replug the device...