如何使用 gdb 在目标 ARM MCU 上调试闪存程序
How to debug a flash program on target ARM MCU with gdb
我正在尝试使用 gdb
在目标 MCU 上调试 ARM 闪存程序
我正在使用 jlinkgdbserver
在目标系统 (cortex-m7) 上设置 gdbserver。我有一个准备调试的小精灵。
我第一次用下面的debug就OK了
> arm-none-eabi-gdb flash_program.elf
(gdb)> target remote localhost:2331 # connect to gdb server on target
(gdb)> load # since it is a flash program, jlink will flash the program
# target is reset to elf entry point
(gdb)> .... (debugging begins)
但是调试到某个地方,又想从入口点调试,我想的办法是再刷一次
(gdb)> Ctrl+D # disconnect the gdbserver
> arm-none-eabi-gdb flash_program.elf
(gdb)> target remote localhost:2331
(gdb)> load
(gdb)> .... (debugging from start again)
所以这似乎有点多余,而且它一遍又一遍地擦除和编程同一个闪存区域,我担心我最终会通过调试损坏存储。
flash程序已经烧录到介质中了,我只是想让target自己复位,然后运行从入口点重新开始。但是我尝试了 monitor reset
和 run
之类的东西。但是目标M7都无法从头开始。
还有其他我可以尝试的 gdb 命令吗?
我使用 STM32F103C8T6
来提供答案,但您只需将其 ROM 基地址 (0x20000000
) 替换为您的 Cortex-M7 使用的地址即可:在我的例子中,我从 0x20000000
加载堆栈指针的初始值,从 0x20000000+4
.
加载程序计数器的初始值
要调试的程序是 stm32f103c8t6.elf
,已经刷写并且确实包含调试符号。
arm-none-eabi-gdb
target remote localhost:2331
0x20000480 in ?? ()
(gdb) monitor halt
(gdb) monitor reset 0
Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
(gdb) monitor reset 1
Resets the core only, not peripherals.
(gdb) monitor reset 2
Resets core & peripherals using RESET pin.
(gdb) symbol-file stm32f103c8t6.elf
Reading symbols from stm32f103c8t6.elf...
(gdb) set $sp = *0x20000000
(gdb) set $pc = *0x20000004
(gdb) stepi
0x200003c2 121 {
(gdb)
0x200003c4 121 {
(gdb) stepi
122 SystemInit(); /* CMSIS System Initialization */
(gdb)
SystemInit () at /opt/arm/ARM.CMSIS.5.6.0//Device/ARM/ARMCM3/Source/system_ARMCM3.c:61
61 {
(gdb)
根据您要使用的重置策略类型,您可能必须在 monitor reset
命令中明确说明:
如 Segger 文档和 this great article 中所述,您可以使用策略编号 0、1 或 2:
# Normal
monitor reset
monitor reset 0
# Core
monitor reset 1
# ResetPin
monitor reset 2
我的理解是,能否使用策略 #2 取决于您的 RESET 引脚的接线方式,即它是否被下拉或未在您的板上。
免责声明:我是软件人,所有硬件相关问题的解释错误都是我的...
gdb 命令 load 将刷新映像,前提是您没有专门设置 link 地址。
你有两个生存选择:
- 设置link地址/调整linker脚本,这样程序就完全在RAM中了。或者
- 保持地址不变,但每次代码更改和编译后,只使用加载一次(使闪存被编程),然后再使用symbol-file 命令只加载符号。
我正在尝试使用 gdb
我正在使用 jlinkgdbserver
在目标系统 (cortex-m7) 上设置 gdbserver。我有一个准备调试的小精灵。
我第一次用下面的debug就OK了
> arm-none-eabi-gdb flash_program.elf
(gdb)> target remote localhost:2331 # connect to gdb server on target
(gdb)> load # since it is a flash program, jlink will flash the program
# target is reset to elf entry point
(gdb)> .... (debugging begins)
但是调试到某个地方,又想从入口点调试,我想的办法是再刷一次
(gdb)> Ctrl+D # disconnect the gdbserver
> arm-none-eabi-gdb flash_program.elf
(gdb)> target remote localhost:2331
(gdb)> load
(gdb)> .... (debugging from start again)
所以这似乎有点多余,而且它一遍又一遍地擦除和编程同一个闪存区域,我担心我最终会通过调试损坏存储。
flash程序已经烧录到介质中了,我只是想让target自己复位,然后运行从入口点重新开始。但是我尝试了 monitor reset
和 run
之类的东西。但是目标M7都无法从头开始。
还有其他我可以尝试的 gdb 命令吗?
我使用 STM32F103C8T6
来提供答案,但您只需将其 ROM 基地址 (0x20000000
) 替换为您的 Cortex-M7 使用的地址即可:在我的例子中,我从 0x20000000
加载堆栈指针的初始值,从 0x20000000+4
.
要调试的程序是 stm32f103c8t6.elf
,已经刷写并且确实包含调试符号。
arm-none-eabi-gdb
target remote localhost:2331
0x20000480 in ?? ()
(gdb) monitor halt
(gdb) monitor reset 0
Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
(gdb) monitor reset 1
Resets the core only, not peripherals.
(gdb) monitor reset 2
Resets core & peripherals using RESET pin.
(gdb) symbol-file stm32f103c8t6.elf
Reading symbols from stm32f103c8t6.elf...
(gdb) set $sp = *0x20000000
(gdb) set $pc = *0x20000004
(gdb) stepi
0x200003c2 121 {
(gdb)
0x200003c4 121 {
(gdb) stepi
122 SystemInit(); /* CMSIS System Initialization */
(gdb)
SystemInit () at /opt/arm/ARM.CMSIS.5.6.0//Device/ARM/ARMCM3/Source/system_ARMCM3.c:61
61 {
(gdb)
根据您要使用的重置策略类型,您可能必须在 monitor reset
命令中明确说明:
如 Segger 文档和 this great article 中所述,您可以使用策略编号 0、1 或 2:
# Normal
monitor reset
monitor reset 0
# Core
monitor reset 1
# ResetPin
monitor reset 2
我的理解是,能否使用策略 #2 取决于您的 RESET 引脚的接线方式,即它是否被下拉或未在您的板上。
免责声明:我是软件人,所有硬件相关问题的解释错误都是我的...
gdb 命令 load 将刷新映像,前提是您没有专门设置 link 地址。 你有两个生存选择:
- 设置link地址/调整linker脚本,这样程序就完全在RAM中了。或者
- 保持地址不变,但每次代码更改和编译后,只使用加载一次(使闪存被编程),然后再使用symbol-file 命令只加载符号。