我正在使用运行RP2040 SMP的FreeRTOS多核MCU;到目前为止,我使用了以下一行命令来重新启动在MCU上运行的代码(在MINGW64 bash中使用openocd ):
/c/path/to/openocd/src/openocd.exe -s /c/path/to/openocd/tcl -f interface/picoprobe.cfg -f target/rp2040.cfg -c "init ; reset ; exit"很多时候,这个命令对我有用,但偶尔我会体验到,当我使用特定的构造(例如timer ISR),并且我使用这个命令时,会出错--要么计时器ISR没有启动,要么一些FreeRTOS任务没有启动。
我花了相当长的时间来思考,这要么是由于我自己编写的代码不当,要么是由于FreeRTOS中的一个bug --然而,我几乎意外地注意到,如果我在gdb会话中重新启动代码而不是上面的命令--这意味着我在一个终端中运行了openocd:
/c/path/to/openocd/src/openocd.exe -s /c/path/to/openocd/tcl -f interface/picoprobe.cfg -f target/rp2040.cfg..。在另一个终端,我让gdb运行:
gdb-multiarch my_progam.elf -ex 'target extended-remote localhost:3333'..。并通过run命令在gdb中重新启动
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: C:\path\to\my_progam\build\my_progam.elf..。然后我的代码开始正常运行,就像预期的那样!!
对于这个问题,我唯一的猜测是,当运行一行openocd命令时,对两个核的访问可能不是“同时”的,因此在MCU上启动例程的时间上可能会出现差异;另一方面,在启动会话时,gdb会停止两个核,因此(我猜)在执行run时,代码会在两个核之间同步重新启动,并且所有的事情都会按预期进行。
那么,我的问题是:是否有一个openocd单行命令,它将重新启动MCU上的代码,就像gdb中的run那样?
发布于 2022-06-27 15:50:39
(张贴在https://github.com/raspberrypi/openocd/issues/64#issuecomment-1167520811上)
好吧,我想我找到了。
基本上,有帮助的是在没有-c命令的情况下运行openocd命令,并使用telnet而不是gdb连接到它。
然后,在telnet中,更容易快速了解命令的效果,并查找帮助。
最后,我意识到rp2040.core0 arp_reset assert 1 ; rp2040.core1 arp_reset assert 1基本上是分别停止每个核心的--对我来说,它与reset halt具有相同的效果;然后让内核再次运行,就像对reset run一样,您可以发出rp2040.core0 arp_reset assert 0 ; rp2040.core1 arp_reset assert 0 --这会产生相同的结果(也就是说,有时计时器/任务不会运行)。
然后,由于上面的调试日志提到了每个被单独锁定的核心,我想:如果一旦内核停止,我们首先运行core 1,怎么办?事实上,这就是解决办法:
> targets
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* rp2040.core0 cortex_m little rp2040.core0.cpu running
1 rp2040.core1 cortex_m little rp2040.core1.cpu running
> rp2040.core0 arp_reset assert 1 ; rp2040.core1 arp_reset assert 1
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
> rp2040.core1 arp_reset assert 0 ; rp2040.core0 arp_reset assert 0请注意,arp_reset assert 0停止重置,也就是说,允许运行cpu核心;我们首先调用rp2040.core1 arp_reset ...来控制哪个先运行,这里是核心1。
对于两个核,reset halt都可以获得相同的结果(而不是通过arp_reset assert 1单独终止它们):
> targets
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* rp2040.core0 cortex_m little rp2040.core0.cpu running
1 rp2040.core1 cortex_m little rp2040.core1.cpu running
> reset halt
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
target halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
> targets
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* rp2040.core0 cortex_m little rp2040.core0.cpu halted
1 rp2040.core1 cortex_m little rp2040.core1.cpu halted
> rp2040.core1 arp_reset assert 0 ; rp2040.core0 arp_reset assert 0最后,我们可以把它放在一条直线上:
/c/path/to/openocd/src/openocd.exe -s /c/path/to/openocd/tcl -f interface/picoprobe.cfg -f target/rp2040.cfg -c "init ; reset halt ; rp2040.core1 arp_reset assert 0 ; rp2040.core0 arp_reset assert 0 ; exit"上面的命令适用于我(当我使用该命令重新启动代码时,所有计时器和FreeRTOS任务都在运行).
https://stackoverflow.com/questions/72745969
复制相似问题