I've got a blackmagic probe
and a board with an STM32F412KB
microcontroller. Flashing the board works great (and fast!) - but I can't find a way to start the firmware after the flash (aside from manually pushing the reset button on the board).
Context:
I'm trying to support the blackmagic probe
in our free microcontroller IDE (https://embeetle.com). Embeetle can already flash firmware using this probe, but the user might forget to push the reset button on his microcontroller board. Displaying a warning message is our last-resort solution. For now, I try to get the blackmagic probe
to work in the same way as the other probes: you click "flash" and you see your firmware running instantly.
1. Hardware Setup
1.1 probe
I've got a blackmagic probe
(see https://1bitsquared.com/products/black-magic-probe and https://github.com/blacksphere/blackmagic/wiki) for flashing and debugging purposes. The probe version is:
Black Magic Probe (Firmware v1.6.1-1-g74af1f5) (Hardware Version 3)
1.2 microcontroller board
The microcontroller board is self-designed:
Here are the relevant parts of the schematic. First of all, the microcontroller:
Here is the physical reset button:
And this is the flash/debug-connector (to be connected to the blackmagic probe
):
As you can see, the flash/debug-connector follows the 10-pin Cortex-debug standard, and can be used for both JTAG
and SWD
flashing/debugging.
2. Software setup
2.1 toolchain
I've got the following toolchain installed on my Windows 10 PC:
gcc-arm-none-eabi-9-2020-q2-update-win32
Which I recently downloaded from:
With this toolchain, I built the microcontroller project. I also use the arm-none-eabi-gdb.exe
tool to interact with the blackmagic probe
(but more on that later).
2.2 Microcontroller project
I've got a microcontroller project at the following location on my Windows 10 PC:
C:/Users/Kristof/beetle_projects/beetle_l412kb
After compilation, the build output ends up in:
C:/Users/Kristof/beetle_projects/beetle_l412kb/build
For example, my .elf
file is at:
C:/Users/Kristof/beetle_projects/beetle_l412kb/build/application.elf
Now I open a console and navigate to the toplevel project folder. Then I invoke the makefile
its flash
target (we'll get to the makefile
in a minute):
$ cd C:/Users/Kristof/beetle_projects/beetle_l412kb
$ make flash -C build -f ../config/makefile "COM=\\.\COM16"
I basically invoke the flash
target from the makefile
and pass it the $(COM)
variable to inform it where the blackmagic probe
is connected.
The relevant part of the makefile is:
ELF_FILE = application.elf
GDB_FLASHFILE = ../config/.gdbinit
GDB_FLASHFLAGS = \
-n \
-batch \
-x $(GDB_FLASHFILE) \
-ex "flash-remote $(ELF_FILE) $(COM)" \
.PHONY: flash
flash: $(ELF_FILE)
arm-none-eabi-gdb $(GDB_FLASHFLAGS)
The flash
target launches arm-none-eabi-gdb
and passes it the $(GDB_FLASHFLAGS)
. These flags point to the following .gdbinit
file where the actual flash instructions are listed inside the flash-remote()
user-defined function:
# This user-defined function flashes the given
# .elf file to the microcontroller and should then
# exit.
define flash-remote
echo \n
echo \n--------------------------------------------------------------------------------
echo \n Run flash-remote function:
echo \n ==========================
echo \n flash-remote(
echo \n elf_file = $arg0,
echo \n com_port = $arg1,
echo \n )
echo \n--------------------------------------------------------------------------------
echo \n
target extended-remote $arg1
monitor version
monitor swdp_scan
attach 1
file $arg0
load
start
detach
quit
end
3. The problem explained
The flashing works great (it's super fast!) and the firmware runs when done. I can see the firmware running because the LED on the board is blinking - that's basically what the firmware does. Unfortunately, the flash-remote()
function hangs at the start
command, probably because GDB is waiting for a breakpoint that never comes.
The goal here is not to debug, but simply to flash the firmware. So I want to exit after the flash. This is what I tried so far:
I simply delete the
start
command. Now the functionflash-remote()
exits cleanly. However, to start the firmware, I need to push the reset button on the board. I'd like to start the firmware without manual intervention.Replacing
start
withmonitor hard_srst
seems to work at first glance (function continues, doesn't hang). However, it causes something to malfunction. Even after pushing the reset button on the board, the firmware doesn't start (LED doesn't blink).
I can't find a way to start the firmware after the flash (aside from manually pushing the reset button on the board).