I am trying to debug a ARM flash program on target MCU using gdb
I am setting up the gdbserver on target system (cortex-m7) with jlinkgdbserver
. And I have a elf ready for debug.
For the first time, it is OK for me do debug with the following
> 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)
However, when debug goes to some place, and I want to debug from the entry point again, the way I figured out is do flashing again
(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)
So this seems a bit redundant, also it erase and program the same flash area again and again, I am afraid I will end up damaging the storage through my debugging.
The flash program has already been burned into the medium, I simply want to let the target to reset itself and run from entry point again. But I tried things like monitor reset
and run
. But the target M7 both can't start from beginning again.
Is there any other gdb command that I can try?
I used an STM32F103C8T6
for providing an answer, but you will just have to replace its ROM base address (0x20000000
) by the one your Cortex-M7 uses: In my case, I loaded the initial value for the stack pointer from 0x20000000
, and the initial value for the program counter from 0x20000000+4
.
The program to be debugged was stm32f103c8t6.elf
, was already flashed and did contain the debug symbols.
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)
Depending on the type of reset strategy you want to use, you may have to explicit it in the monitor reset
command:
As explained in the Segger documentation and this great article, you can use strategy number 0, 1 or 2:
# Normal
monitor reset
monitor reset 0
# Core
monitor reset 1
# ResetPin
monitor reset 2
My understanding is that being able to use strategy #2 depends on how your RESET pin was wired, i.e. if it is pulled-down or not on your board.
Disclaimer: I am a software person, and all interpretation errors related to hardware-related questions are mine...