Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1809906
coresight: prefer breakpoint halt reasons over debug requests
DavidLesnjak Oct 8, 2026
4c501bc
gdbserver: keep trace errors from stopping run control
DavidLesnjak Oct 8, 2026
91bec3d
gdbserver: release client connections once
DavidLesnjak Oct 8, 2026
a8e1283
gdbserver: start packet I/O before attaching clients
DavidLesnjak Oct 8, 2026
d5bd5ee
gdbserver: disable non-stop mode with GDB File-I/O
DavidLesnjak Oct 8, 2026
738f047
gdbserver: release server resources once
DavidLesnjak Oct 8, 2026
588e15a
gdbserver: track target halts across run boundaries
DavidLesnjak Oct 8, 2026
10c4215
gdbserver: retain target run state after reset-run
DavidLesnjak Oct 8, 2026
9b9b796
gdbserver: service semihosting without blocking File-I/O
DavidLesnjak Oct 8, 2026
5573a66
options: add live status fault retry timeout
DavidLesnjak Oct 8, 2026
e537ba8
gdbserver: coordinate target service and client run control split
DavidLesnjak Oct 8, 2026
73a3613
gdbserver: handle interrupts and faults during all-stop runs
DavidLesnjak Oct 8, 2026
e8abe97
target: skip unmanaged breakpoint instructions
DavidLesnjak Oct 8, 2026
1516de8
gdbserver: resume past initial unmanaged BKPT and semihosting stops
DavidLesnjak Oct 8, 2026
6f5aab2
gdbserver: restore target after failed client attachment
DavidLesnjak Oct 8, 2026
e544f56
rtt: limit discovery warnings and handle missing config
DavidLesnjak Oct 8, 2026
1e175d0
gdbserver: discover configured RTT channels in service thread
DavidLesnjak Oct 8, 2026
0fcec4b
gdbserver: pass per-core RTT configuration to servers
DavidLesnjak Oct 8, 2026
2585fa3
gdbserver: assemble SystemView recordings on shutdown
DavidLesnjak Oct 8, 2026
a6676bd
gdbserver_cmd: update trace workflow in subcommand
TeoMahnic Oct 8, 2026
5763b2c
run_cmd: update trace workflow in subcommand
TeoMahnic Oct 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,15 @@ applies while the target is running after a resume operation in the debugger and
it to halt again.
</td></tr>

<tr><td>live.status_fault_retry_timeout</td>
<td>float</td>
<td>No default</td>
<td>
Timeout in seconds for retrying target status reads that fail with a transfer error while a server
monitors a core. A successful read clears the retry period. If the timeout expires, the server
instance for that core exits. If the option is omitted, retries continue indefinitely.
</td></tr>

<tr><td>gdbserver_port</td>
<td>int</td>
<td>3333</td>
Expand Down
4 changes: 4 additions & 0 deletions pyocd/core/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ class OptionInfo(NamedTuple):
"Duration in seconds that a failed target status check will be retried before an error is raised. "
"Only applies while the target is running after a resume operation in the debugger and pyOCD is waiting "
"for it to halt again."),
OptionInfo('live.status_fault_retry_timeout', float, None,
"Timeout in seconds for retrying target status reads that fail with a transfer error while a server "
"monitors a core. A successful read clears the retry period. If the timeout expires, the server "
"instance for that core exits. If the option is omitted, retries continue indefinitely."),
OptionInfo('gdbserver_port', (int, tuple), 3333,
"Base TCP port for the gdbserver."),
OptionInfo('persist', bool, False,
Expand Down
3 changes: 3 additions & 0 deletions pyocd/core/soc_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ def write_core_registers_raw(self, reg_list: Sequence[CoreRegisterNameOrNumberTy
def find_breakpoint(self, addr: int) -> Optional[Breakpoint]:
return self.selected_core_or_raise.find_breakpoint(addr)

def skip_breakpoint_instruction(self, exclude_semihosting: bool = False) -> bool:
return self.selected_core_or_raise.skip_breakpoint_instruction(exclude_semihosting)

def set_breakpoint(self, addr: int, type: Target.BreakpointType = Target.BreakpointType.AUTO) -> bool:
return self.selected_core_or_raise.set_breakpoint(addr, type)

Expand Down
3 changes: 3 additions & 0 deletions pyocd/core/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ def write_core_registers_raw(self, reg_list: Sequence[CoreRegisterNameOrNumberTy
def find_breakpoint(self, addr: int) -> Optional[Breakpoint]:
raise NotImplementedError()

def skip_breakpoint_instruction(self, exclude_semihosting: bool = False) -> bool:
raise NotImplementedError()

def set_breakpoint(self, addr: int, type: BreakpointType = BreakpointType.AUTO) -> bool:
raise NotImplementedError()

Expand Down
27 changes: 24 additions & 3 deletions pyocd/coresight/cortex_m.py
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,27 @@ def resume(self) -> None:
def find_breakpoint(self, addr: int) -> Optional[Breakpoint]:
return self.bp_manager.find_breakpoint(addr)

def skip_breakpoint_instruction(self, exclude_semihosting: bool = False) -> bool:
"""@brief Skip an BKPT instruction.

@return True if a BKPT instruction was skipped, otherwise False.
"""

pc = self.read_core_register('pc')

instruction = self.read16(pc)
if (instruction & 0xff00) != 0xbe00:
return False

if exclude_semihosting and instruction == 0xbeab:
return False

self.write_core_register('pc', pc + 2)
LOG.debug("Skipped breakpoint at 0x%08x", pc)
self._run_token += 1

return True

def check_reg_list(self, reg_list: Sequence[CoreRegisterNameOrNumberType]) -> None:
"""@brief Sanity check register values and raise helpful errors."""
for reg in reg_list:
Expand Down Expand Up @@ -1621,16 +1642,16 @@ def get_halt_reason(self) -> Optional[Target.HaltReason]:
@return @ref pyocd.core.target.Target.HaltReason "Target.HaltReason" enumerator or None.
"""
dfsr = self.read32(CortexM.DFSR)
if dfsr & CortexM.DFSR_HALTED:
reason = Target.HaltReason.DEBUG
elif dfsr & CortexM.DFSR_BKPT:
if dfsr & CortexM.DFSR_BKPT:
reason = Target.HaltReason.BREAKPOINT
elif dfsr & CortexM.DFSR_DWTTRAP:
reason = Target.HaltReason.WATCHPOINT
elif dfsr & CortexM.DFSR_VCATCH:
reason = Target.HaltReason.VECTOR_CATCH
elif dfsr & CortexM.DFSR_EXTERNAL:
reason = Target.HaltReason.EXTERNAL
elif dfsr & CortexM.DFSR_HALTED:
reason = Target.HaltReason.DEBUG
else:
reason = None
return reason
Expand Down
6 changes: 3 additions & 3 deletions pyocd/coresight/cortex_m_v8m.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,7 @@ def get_halt_reason(self):
@return @ref pyocd.core.target.Target.HaltReason "Target.HaltReason" enumerator or None.
"""
dfsr = self.read32(self.DFSR)
if dfsr & self.DFSR_HALTED:
reason = Target.HaltReason.DEBUG
elif dfsr & self.DFSR_BKPT:
if dfsr & self.DFSR_BKPT:
reason = Target.HaltReason.BREAKPOINT
elif dfsr & self.DFSR_DWTTRAP:
reason = Target.HaltReason.WATCHPOINT
Expand All @@ -276,6 +274,8 @@ def get_halt_reason(self):
reason = Target.HaltReason.EXTERNAL
elif dfsr & self.DFSR_PMU:
reason = Target.HaltReason.PMU
elif dfsr & self.DFSR_HALTED:
reason = Target.HaltReason.DEBUG
else:
reason = None
return reason
Expand Down
3 changes: 3 additions & 0 deletions pyocd/coresight/generic_mem_ap.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def resume(self):
def find_breakpoint(self, addr):
return None

def skip_breakpoint_instruction(self, exclude_semihosting: bool = False) -> bool:
return False

def read_core_register(self, reg):
raise exceptions.CoreRegisterAccessError("GenericMemAPTarget does not support core register access")

Expand Down
Loading
Loading