pyocd / pyocd/pyOCD

PyOCD too pessimistic with occasional SWD communication glitches?

Open
#1,165 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

improvement
Dominant language
Python
Stars
1.5k
Forks
560
Avg merge
1h 41m
Merged PRs (30d)
3

Description

I'm receiving occasional memory transfer faults while code is running (seemingly always while querying the target state in gdbserver.py), resulting in the following trace:

0183965:WARNING:gdbserver:Exception while target was running: Memory transfer fault (read) @ 0xe000edf0-0xe000edf7
Traceback (most recent call last):
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/gdbserver/gdbserver.py", line 609, in resume
    if self.target.get_state() == Target.State.HALTED:
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/coresight/cortex_m.py", line 831, in get_state
    dhcsr = self.read_memory(CortexM.DHCSR)
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/coresight/cortex_m.py", line 436, in read_memory
    result = self.ap.read_memory(addr, transfer_size, now)
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/probe/stlink_probe.py", line 255, in read_memory
    result = conversion.byte_list_to_u32le_list(self._link.read_mem32(addr, 4, self._apsel))[0]
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/probe/stlink/stlink.py", line 385, in read_mem32
    return self._read_mem(addr, size, Commands.JTAG_READMEM_32BIT, self.MAXIMUM_TRANSFER_SIZE, apsel)
  File "/home/antti/.local/lib/python3.8/site-packages/pyocd/probe/stlink/stlink.py", line 343, in _read_mem
    raise exc
pyocd.core.exceptions.TransferFaultError: Memory transfer fault (read) @ 0xe000edf0-0xe000edf7

I don't quite understand the mechanism, but this fault will cause the debug session to fail. This is quite annoying as the fault sometimes occurs within 5 minutes.

My SWD signal integrity is probably not the best, which may explain the origins of the faults themselves. However, just as a test I added a retry loop in stlink_probe.py in the read_memory function. Turns out that in my case the read succeeds on the next try, and the debug session continues to work despite a single read failure.

Would it make sense for PyOCD to allow a few retries before raising an exception in such a case?

Background:

  • I'm running PyOCD 0.30.3 on a Linux machine (Ubuntu 20.04)
  • I'm debugging a custom board, which has SWD through a pogo pin connection. MCU is STM32F103C8 (very boring indeed).
  • Adapter is an authentic ST-LINK/V2
  • I'm debugging in STM32CubeIDE. As a side note, the built-in ST-LINK gdb server has no stability issues with the same config, but otherwise I would prefer PyOCD.
  • My pyocd.yaml:
    target_override: stm32f103c8
    enable_semihosting: False
    swv_system_clock: 48000000
    swv_clock: 2000000
    swv_raw_port: 3344
    enable_swv: True

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with gdbserver.py's resume path and CortexM.get_state(), then inspect stlink_probe.py's read_memory retry experiment and the underlying ST-LINK read path. Reproduce an intermittent transfer fault if possible; done means transient SWD read failures are retried without ending the GDB session, while persistent faults still raise an exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools, embedded-iot
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.