In yesterday's log, I wrote about not being able to connect the STLink v2 to the STM32 of the BlackIce-II board.
Right now, that still doesn't work, but I found a work-around: I installed the wonderful BlackMagic Probe firmware on the Blue Pill STM32F103 board, which converts the Blue Pill into a debugging dongle that's actually more powerful than the STLink v2!
An STLink v2 is essentially a protocol converter from USB to SWD. You still need OpenOCD as an intermediary to link GDB to your STM32.
Not so with the BlackMagic Probe: it has acts like a serial port on the USB side, has a GDB server built-in which drives a SWD or JTAG interface. OpenOCD is not needed anymore: you connect your GDB straight to the dongle.
How did I get there?
Install Black Magic Probe on the Blue Pill
This turned out to be a combination of this article: "Converting an STM32F103 board to a Black Magic Probe"and this article: "Programming an STM32F103XXX with a generic "ST Link V2" programmer from Linux" (which I already reference earlier.)
The first article assumes that you don't have an STLink v2 dongle and compiles then installs the BlackMagic firmware using a USB to Serial dongle instead. The second one tells you how to install anything with the STLink dongle.
I wanted to use the STLink dongle to install the BlackMagic firmware.
All in all, the procedure was pretty straightforward.
- Compile the BlackMagic firmware until you have blackmagic_dfu.bin and black magic.bin
- Download BlackMagic from GitHub
- cd src
- make clean && make PROBE_HOST=stlink
- Install blackmagic_dfu.bin with the STLink dongle
- openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/local/share/openocd/scripts/target/stm32f1x.cfg
- telnet localhost 4444
- reset halt (in combination with pressing the Blue Pill reset button)
- flash write_image erase blackmagic_dfu.bin 0x08000000
- Once installed, the Blue Pill device is now DFU capable, which means that new firmware can be installed over USB. You do not need the STLink dongle anymore to install additional firmware!
- Install black magic.bin (without STLink)
- dfu-util -d 1d50:6018,:6017 -s 0x08002000:leave -D blackmagic.bin
In the process of all this, I learned a little bit about this all works:
- The STM32F1 starts executing at address 0x08000000 and thus when the blackmagic_dfu.bin firmware was installed, it's flashed to that address.
- The blackmagic_dfu.bin has two features:
- It tests if there is valid firmware at 0x08002000. If there is, it jumps to that address and its job is done. You can see that piece of code here.
- When there isn't any valid code, then it sets itself up as a USB DFU device, making it possible to flash valid firmware. You can see this just a few lines further down.
- Consequently, blackmagic.bin is located at address 0x08002000. Since it completely takes over the board, this one also need to implement DFU mode, otherwise you'd need an additional dongle (like the original STLink) to install improved BlackMagic firmware later on!
- The BlackMagic firmware implements 3 'functionalities' on a single USB device:
- GDB (which uses a USB-to-Serial port)
- This ultimately controls SWD and JTAG pins on your Blue Pill
- UART (also using USB-to-Serial port)
- This controls UART pins on the Blue Pill.
- Instead of using the standard STM32 libraries, BlackMagic uses libopencm3, which is an open-source equivalent that can be used to many different Cortex devices from other chip companies.
Connecting the Black Magic to the BlackIce-II
I wired the following signals:
- Blue Pill GND -> GND (pin 9 of the BlackIce-II RPi connector)
- Blue Pill SWDIO (pin PB14) -> SWDIO (pin 11 of the BlackIce-II RPi connector)
- Blue Pill SWCLK (pin PA5) -> SWCLK (pin 7 of the BlackIce-II RPi connector)
Once you have BlackMagic Probe running on the Blue Pill, you can connect to it directly with gdb:
- arm-none-eabi-gdb -ex "target extended-remote /dev/ttyACM0"
- On my Linux machine, the BlackMagic Probe created /dev/ttyACM0 (GDB) and /dev/ttyACM1 (UART). If you do 'ls /dev/serial/by-id', you can see more descriptive names to connect to.
- You should see "Remove debugging using <some interface> :
ubuntu@ubuntu-xenial:~/projects/BlackIce-II/firmware/iceboot$ arm-none-eabi-gdb -ex "target extended-remote /dev/ttyACM0" GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 188.8.131.5271128-git Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word". Remote debugging using /dev/ttyACM0 (gdb)
- You now need to scan for STM32 devices:
- monitor swdp_scan
Note that this didn't work at first. Initially, I saw the following:
(gdb) monitor swdp_scan Target voltage: unknown SW-DP scan failed!
It took me a long to time figure what was wrong. In the end, I solved it by wiring an additional GND wire between the Blue Pill board and the BlackIce-II board. So simple!
(gdb) monitor swdp_scan Target voltage: unknown Available Targets: No. Att Driver 1 STM32L4xx
- Next, you need to tell GDB to connect to this device:
- attach 1
(gdb) attach 1 Attaching to Remote target warning: No executable has been specified and target does not support determining executable automatically. Try using the "file" command. 0x080008e2 in ?? ()
What happened now is that GDB has taken control of the ARM CPU. Whatever it was executing has been stopped now and that is that.
If you never replaced the firmware of the BlackIce-II STM32 controller, you interrupted the iceboat firmware, which allows one to download a new FPGA bitstream over the USB-to-Serial port.
Debugging Firmware on the BlackIce-II STM32
For now, let's just use an example of the existing firmware.
- Recompile the iceboat firmware as described in my wiki page here.
- You will now have a file called iceboot.elf in the ./output directory
- While in the ./firmware/iceboot directory, attach gdb to the STM32 CPU as described earlier.
- Press the reset button of the BlackIce-II board!
- This reset the CPU back to its starting position. But since GDB is attached now, it will stay there.
- Load the recompiled firmware:
- file ./output/iceboot.elf
- Set a breakpoint at the start of the C program
- br main
- Start executing
- If all goes well, the GDB will now be waiting at the first command of main.
It looks like this on my console:
Remote debugging using /dev/ttyACM0 (gdb) atta 1 Attaching to Remote target warning: No executable has been specified and target does not support determining executable automatically. Try using the "file" command. 0x080011d6 in ?? () (gdb) file ./output/iceboot.elf A program is being debugged already. Are you sure you want to change the file? (y or n) y Reading symbols from ./output/iceboot.elf...done. (gdb) br main Breakpoint 1 at 0x80012b4: file main.c, line 95. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/ubuntu/projects/BlackIce-II/firmware/iceboot/output/iceboot.elf Note: automatically using hardware breakpoints for read-only addresses. Breakpoint 1, main () at main.c:95 95 HAL_Init(); (gdb)