In my previous post I was showing a very elementary but outright inefficient way to debug tricky (Arm Cortex-M4) code which was relocated. The full case was/is: There is a bootloader which loads actual firmware binary. Bootloader is at 0x8000000, firmware at 0x8005000. We used a method to load debug values to registers we were monitoring. It worked but was complex and did not address the root cause of mismatched symbols. There is however a way to make the relocated firmware binary to correspond 100% to the debug symbols and debugger screen. Read below to know more.
One sour thing is that we have (at least in STM32CubeIDE) our fine symbol address possibility:
But whatever you put in, the firmware code after the jump from bootloader has its own adventures:
Now lets fix this. And lets start from the beginning.
Disconnect and reconnect target, just in case:
Select properties for bootloader (shortcut while project selected in Project Explorer: Alt+Enter):
Select Run/Debug Settings => L432KC_Bootloader => Edit…
Then verify settings for bootloader:
Here we verified that we start at beginning of flash (0x8000000) via vector table, download bootloader to flash and load bootloader symbols.
Next verify firmware settings:
Her we flash the firmware to offset 0x5000 and DO NOT LOAD SYMBOLS. Loading symbols at this point can mess up whole thing.
When we are done, press Apply and Close:
Lets start bootloader in Debug mode:
If it stops, just press continue:
Let it run and press pause. See that you are now in source unknown to debugger:
Now the trick here is go your filesystem and locate the firmware binary which is offsetted. Get the full pathname of the .elf to notepad. Then convert slashes to double slashes and copy the result to clipboard:
Now time for the magic command. Go to Debugger Console tab and punch in:
symbol-file C:\\repos\\L432KC-BL-FW\\L432KC_Firmware_anywhere\\Debug\\L432KC_Firmware_anywhere.elf -o 0x5000
Step to the next line (hotkey: F5). You see now that the source code is resolved!Scroll to beginning of main and add a breakpoint to firmware main(), then reset chip to restart session:
Now FINALLY we land safely to the main() breakpoint! Now we can start our actual work 😀