pyocd / pyOCD

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

gdbserver `run` and reset #1633

Open via opened 1 year ago

via commented 1 year ago

Attaching gdb to the pyocd gdbserver and then running run results in pyocd severing the gdb connection:

gdb-multiarch example.elf
target extended-remote :3333
...
run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: example.elf
Remote communication error.  Target disconnected.: Connection reset by peer.
(gdb) 

when running pyocd with: pyocd gdbserver --target s32k344 --persist

I frequently use run to restart a target without re-loading, when I want to start at the reset vector again. After a little bit of digging, I found that monitor reset halt core accomplished the same thing (monitor reset halt by itself does not), but given that using run has worked for me on other setups (stm32 targets with openocd and blackmagic probe), I wasn't sure if this behavior was intentional.

Digging through gdbserver and using the trace debugging, it looks like run issues a kill and then a restart. The handling of the kill in gdbserver.py seems to be what actually severs the connection. If I mimic the logic of detach() and do

-        self.detach_event.set()
+        if not self._is_extended_remote:
+            self.detach_event.set()

It makes gdb happy, it remains connected, and superficially appears to work (but doesn't due to the below).

The second issue seems to be that the default reset is insufficient for the s32k344. There is an override here: https://github.com/pyocd/pyOCD/blob/main/pyocd/target/builtin/target_S32K344.py#L520

It doesn't seem as though the call to reset_and_halt() in gdbserver uses that code though, and it uses the generic cortex_m logic. I am guessing this is why I have to also explicitly monitor reset halt core? What would be the best way to make this use the s32k344-specific overrides?

If I explicitly specify that reset method:

-        self.target.reset_and_halt()
+        self.target.reset_and_halt(self.target.ResetType.SW_VECTRESET)

the run behavior is exactly what I would expect, and a breakpoint set in the reset vector is immediately reached after running run (and y to restart, etc).

Thank you!

elfmimi commented 9 months ago

I suppose you can do monitor set reset-type SW_VECTRESET . then reset and run should respect that setting.