首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Openocd单线为适当的多核MCU复位?

Openocd单线为适当的多核MCU复位?
EN

Stack Overflow用户
提问于 2022-06-24 15:00:21
回答 1查看 128关注 0票数 0

我正在使用运行RP2040 SMP的FreeRTOS多核MCU;到目前为止,我使用了以下一行命令来重新启动在MCU上运行的代码(在MINGW64 bash中使用openocd ):

代码语言:javascript
复制
/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:

代码语言:javascript
复制
/c/path/to/openocd/src/openocd.exe -s /c/path/to/openocd/tcl -f interface/picoprobe.cfg -f target/rp2040.cfg

..。在另一个终端,我让gdb运行:

代码语言:javascript
复制
gdb-multiarch my_progam.elf -ex 'target extended-remote localhost:3333'

..。并通过run命令在gdb中重新启动

代码语言:javascript
复制
(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那样?

EN

回答 1

Stack Overflow用户

发布于 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,怎么办?事实上,这就是解决办法:

代码语言:javascript
复制
> 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单独终止它们):

代码语言:javascript
复制
> 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

最后,我们可以把它放在一条直线上:

代码语言:javascript
复制
/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任务都在运行).

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72745969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档