Live Debugging with Raspberry Pi Pico

Following the instructions in "Getting started with Raspberry Pi Pico" [1] I was able to set up a "picoprobe", which is a Pico running picoprobe firmware, and connect it to the debug ports on a Pico running Mecrisp Stellaris Forth. The set up looks a little funny because my second breakout board hadn't arrived yet, so I just attached some terminal blocks directly onto the picoprobe, but it works.

picoprobe connected to Pico running Mecrisp

Then, continuing to follow the instructions, I was able to build the rp2040 branch of openocd, connect openocd to the picoprobe, and attach a gdb-arm session to it.

christopher@theoden ~/Build/openocd$ sudo ~/local/bin/openocd -f interface/picoprobe.cfg -f target/rp2040.cfg -s tcl
Password: 
Open On-Chip Debugger 0.11.0-g610f137 (2022-03-30-08:35)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'swd'
adapter speed: 5000 kHz

Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : RP2040 Flash Bank Command
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x10000001
Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints
Info : rp2040.core1: hardware has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections
Info : accepting 'gdb' connection on tcp/3333
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
target halted due to debug-request, current mode: Thread 
xPSR: 0x81000000 pc: 0x2000257c msp: 0x20020350
Info : RP2040 B0 Flash Probe: 2097152 bytes @10000000, in 512 sectors

Info : New GDB Connection: 1, Target rp2040.core0, state: halted
Warn : Prefer GDB command "target extended-remote 3333" instead of "target remote 3333"

When GDB connects to openocd, then automatically the system is halted at its current point of execution. I am able to continue execution of Mecrisp using the "continue" command, and halt it again with "Ctrl-C". When halted, the "i r" command allows me to view the registers, and "disas $pc,+40" allows me to view the instructions at the current location specified by the Program Counter.

(gdb) continue
Continuing.
^Ctarget halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00

Thread 1 received signal SIGINT, Interrupt.
0x2000257c in ?? ()
(gdb) i r
r0             0x2000492e          536889646
r1             0x200200bb          537002171
r2             0x0                 0
r3             0x34                52
r4             0x0                 0
r5             0x2003fee4          537132772
r6             0xffffffff          -1
r7             0x20020270          537002608
r8             0xffffffff          -1
r9             0xffffffff          -1
r10            0xffffffff          -1
r11            0xffffffff          -1
r12            0x4001801c          1073840156
sp             0x20020350          0x20020350
lr             0x20002571          536880497
pc             0x2000257c          0x2000257c
xPSR           0x81000000          -2130706432
msp            0x20020350          0x20020350
psp            0xfffffffc          0xfffffffc
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0
(gdb) disas $pc,+40
Dump of assembler code from 0x2000257c to 0x200025a4:
=> 0x2000257c:	mvns	r6, r6
   0x2000257e:	pop	{pc}
   0x20002580:	b.n	0x20002584
   0x20002582:	ands	r0, r0
   0x20002584:	ldmia	r5, {r0, r1, r2, r3, r4, r5, r7}
   0x20002586:	lsls	r7, r7, #7
   0x20002588:	and.w	r0, r0, #2147483648	; 0x80000000
   0x2000258c:	ldrb	r6, [r7, #31]
   0x2000258e:	movs	r4, r7
   0x20002590:	stmia	r0!, {}
   0x20002592:	ands	r0, r0
   0x20002594:	strh	r0, [r0, #0]
   0x20002596:	ands	r5, r0
   0x20002598:	lsls	r4, r1, #8
   0x2000259a:	movs	r0, r0
   0x2000259c:	strh	r0, [r0, #0]
   0x2000259e:	ands	r0, r0
   0x200025a0:	ands	r0, r0
   0x200025a2:	ands	r2, r0
End of assembler dump.

Because I tied together the UART lines, I can still interact with the Forth system in the normal way over sterm.

christopher@theoden ~$ sterm -n /dev/ttyACM0 -s 115200
2 3 * .
2 3 * . 6  ok.

Now that I can debug a live system, I was planning to study my ARM manual [2] again and learn more about the different registers and such like.

[1]

Getting started with Raspberry Pi Pico

[2]

ARMv6-M Architecture Reference Manual