If you need to debug your printer's firmware, you've probably read my previous post already. If not, I advice you to read it.
This post is about solving the remaining issues and/or shortcomings with the debugging so that a debugging session is 100% stable and reproductible.
I'm focusing on MKS Robin Nano v1.2 board because it's what I have. The instructions below are generic enough to work on any board, but the provided bootloader file is specific to this board so you must not use it on any other board.
You need a ST-Link V2 USB dongle (or, if you have an older ST-Link dongle, it'll also work).
You need OpenOCD installed (see previous post for instructions)
After all the painful steps below, you'll get:
run
in GDB, it'll reload symbols from the current ELF file so all symbols will now be found by GDB)As you might have experienced already, debugging with ST-Link V2 is painful when there is a locked bootloader installed on the flash (default when you receive the board). It prevents you from manipulating the flash content (so you must copy the .BIN file to the SD card after each build, and set some specific "synchronization" point so that you can Ctrl+C in GDB later on and change state to continue). You have many limitation to the GDB commands you can use (like 'run' is not working correctly).
This all happens because of the lock state of the flash memory. This is a protection for STM32 microcontroller to prevent reading the flash content, and, as such, prevent loosing trade secret. Unfortunately, if you unlock the flash memory, the flash content is erased, so you're going to loose the bootloader. Without a bootloader, your board will no longer boot (or you'll need to modify a lot of stuff in internal Marlin core).
The stupid thing about this system is that the bootloader implement a feature to erase / read and write the flash, since it's able to update the firmware. So, nothing prevents a developer to write a software that's dumping the bootloader and saving it on the SD card, rendering the protection useless.
Don't worry, it was already done and I'm linking here the dump file so you don't have to go into a huge mess. The "official bootloader" from this source code repository does not work, it's just too big.
Beware that the bootloader binary above only work for MKS Robin Nano v1.2
board, if you have a different board, it'll fail and brick your printer.
If you have another board, you must locate a valid bootloader binary for it, feel free to add in the comment your bootloader.bin
for your board.
Ok, now we have all we need, let's start hacking!
STM32 has a protection system that, once activated, prevent external access to flash content. By external, I mean via JTAG/SWD. This protection has 3 levels:
If you are in the Level 2 case, bad luck. This is very unlikely, since it would mean that the bootloader would be a lot more complex. We are going to unlock the CPU so it resets to level 0. Doing so means erasing the flash, so make sure you have a valid bootloader .BIN file before attempting anything else, else you'll brick your board
Ok, so you'll need to trigger OpenOCD and start GDB (see previous post). Once in GDB, you'll need to connect to the board like this:
(gdb) tar ext:3333
blah blah : success
(gdb)
Then we need to send a command to OpenOCD directly, via the GDB monitor
command:
(gdb) monitor reset halt
(gdb) monitor stm32f1x unlock 0
(gdb) monitor reset halt
The second line erases all the flash. This means that after calling this line, your board will no longer boot (unless you proceed to next step)
Once the flash is completely erased, you'll need to flash the bootloader again. I'm doing this via the command:
(gdb) monitor program bootloader.bin 0x8000000
(gdb) monitor reset run
After the second command, the display on the printer should display its usual Booting
with its ugly chime.
If this does not work, you can use st-flash from st-util, basically you want to flash the bootloader.bin file at address 0x8000000
(that's the beginning of the flash address).
Ok, you've made the hardest work, let's explore what this gives you:
(gdb) file .pio/build/mks_robin_nano35/firmware.elf
(gdb) run
Reloading source file because it has changed...
(gdb) monitor program .pio/build/mks_robin_nano35/firmware.bin 0x8007000
Hope it helps!