Flashing a device occasionally crashes pyOCD when multiple devices are connected
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.5k
- Forks
- 560
- Avg merge
- 1h 41m
- Merged PRs (30d)
- 3
Description
OS: MacOS 10.12.16
pyOCD: 0.21.0
Devices: nRF51-DK, F042k6, Disco-L475, Nucleo-F446, etc.
When multiple devices are connected, the uid switch needs to be provided in order to target the correct device during a flash operation. e.g.:
./pyocd flash --uid 1100021844203120324C46383230353138303035B9C7DFD8 --target nrf51 --erase=chip "/Users/bob/Mbed Programs/mbed-os-example-blinky-tes/BUILD/NRF51_DK/ARMC6/mbed-os-example-blinky.hex"
This can often fail with the following error:
0000140:ERROR:__main__:uncaught exception: 'utf16' codec can't decode byte 0x6c in position 30: truncated data
Traceback (most recent call last):
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/__main__.py", line 304, in run
self._commands[self._args.cmd]()
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/__main__.py", line 369, in do_flash
**convert_session_options(self._args.options))
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/core/helpers.py", line 141, in session_with_chosen_probe
allProbes = ConnectHelper.get_all_connected_probes(blocking=blocking, unique_id=board_id)
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/core/helpers.py", line 78, in get_all_connected_probes
allProbes = DebugProbeAggregator.get_all_connected_probes(unique_id=unique_id)
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/aggregator.py", line 32, in get_all_connected_probes
probes += cls.get_all_connected_probes()
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/cmsis_dap_probe.py", line 73, in get_all_connected_probes
return [cls(dev) for dev in DAPAccess.get_connected_devices()]
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/pydapaccess/dap_access_cmsis_dap.py", line 449, in get_connected_devices
all_interfaces = _get_interfaces()
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/pydapaccess/dap_access_cmsis_dap.py", line 56, in _get_interfaces
interfaces += INTERFACE[USB_BACKEND_V2].get_all_connected_interfaces()
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py", line 178, in get_all_connected_interfaces
for board in all_devices:
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/usb/core.py", line 1249, in device_iter
if _interop._all(tests) and (custom_match is None or custom_match(d)):
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py", line 274, in __call__
cmsis_dap_interface = usb.util.find_descriptor(config, custom_match=match_cmsis_dap_interface_name)
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/usb/util.py", line 190, in find_descriptor
return _interop._next(desc_iter(**args))
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/usb/_interop.py", line 66, in _next
return next(iter)
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/usb/util.py", line 183, in desc_iter
if _interop._all(tests) and (custom_match is None or custom_match(d)):
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py", line 256, in match_cmsis_dap_interface_name
interface_name = usb.util.get_string(desc.device, desc.iInterface)
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/site-packages/usb/util.py", line 330, in get_string
return buf[2:buf[0]].tostring().decode('utf-16-le')
File "/Users/robmor01/mbed-studio-tools/python/lib/python2.7/encodings/utf_16_le.py", line 16, in decode
return codecs.utf_16_le_decode(input, errors, True)
UnicodeDecodeError: 'utf16' codec can't decode byte 0x6c in position 30: truncated data
When this happens, the device is left in an odd state and can only be recovered by flashing without the uid switch (and other devices disconnected so it becomes the default) or by using mass storage device flash.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the flash command with multiple connected devices, then start at pyocd/probe/pydapaccess/interface/pyusb_v2_backend.py and follow get_connected_devices() through the USB descriptor lookup shown in the traceback. Use the reported UnicodeDecodeError as the failure signal; done means selecting a device by uid no longer crashes and the targeted device can be flashed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, python
- Domain
- devtools, embedded-iot
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100