- Soldering tools.
- 4x Female header jumper wires.
- 2x ST-Link v2 clone, one is used as a target and the other is used as a programmer.
- This guide has only been tested on ST-Link v2 clone with STM32F103C8T6 mounted on it.
- This guide was written and tested on macOS Sonoma. It should work on Linux, and also Windows under WSL/WSL2.
Turn Your $2 STLink Clone Into a Black Magic Probe:
Black Magic Probe out of cheap ST-Link programmers:
STM32F103C8T6 with 128kB Flash:
BlackMagic Probe, VSCode, Excellent Cortex-Debug:
- Identify 3.3V, SWDIO, SWCLK, and GND on the target board.
- Solder some wires on taget board and connect to programmer's 3.3V, SWDIO, SWCLK, and GND.
- Plug in the programmer to PC USB port.
(base) macos@Eka-MacBook-Pro Developer % git clone https://github.com/blacksphere/blackmagic.git
Cloning into 'blackmagic'...
remote: Enumerating objects: 39109, done.
remote: Counting objects: 100% (8017/8017), done.
remote: Compressing objects: 100% (986/986), done.
remote: Total 39109 (delta 7336), reused 7065 (delta 7031), pack-reused 31092 (from 2)
Receiving objects: 100% (39109/39109), 10.60 MiB | 1.50 MiB/s, done.
Resolving deltas: 100% (31162/31162), done.
(base) macos@Eka-MacBook-Pro Developer % cd blackmagic
(base) macos@Eka-MacBook-Pro blackmagic % meson setup build --cross-file cross-file/arm-none-eabi.ini --cross-file cross-file/stlink.ini -Dprobe=stlink -Dbmd_bootloader=true -Dtargets=stm -Drtt_support=false
The Meson build system
Version: 1.5.1
Source dir: /Users/macos/Developer/blackmagic
Build dir: /Users/macos/Developer/blackmagic/build
Build type: cross build
Project name: Black Magic Debug
Project version: 1.10.0
C compiler for the host machine: arm-none-eabi-gcc (gcc 13.3.1 "arm-none-eabi-gcc (Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24)) 13.3.1 20240614")
C linker for the host machine: arm-none-eabi-gcc ld.bfd 13.3
C compiler for the build machine: cc (clang 16.0.0 "Apple clang version 16.0.0 (clang-1600.0.26.6)")
C linker for the build machine: cc ld64 1115.7.3
Build machine cpu family: aarch64
Build machine cpu: aarch64
Host machine cpu family: arm
Host machine cpu: arm
Target machine cpu family: arm
Target machine cpu: arm
Compiler for C supports arguments -Warith-conversion: YES
Compiler for C supports arguments -w24244: NO
Compiler for C supports arguments -Wbad-function-cast: YES
Compiler for C supports arguments -Wcast-function-type: YES
Compiler for C supports arguments -Wcast-qual: YES
Compiler for C supports arguments -Wdangling-else: YES
Compiler for C supports arguments -Wdouble-promotion: YES
Compiler for C supports arguments -Wduplicated-branches: YES
Compiler for C supports arguments -w24754: NO
Compiler for C supports arguments -Wfloat-conversion: YES
Compiler for C supports arguments -Wformat-overflow=2: YES
Compiler for C supports arguments -Wformat-truncation: YES
Compiler for C supports arguments -Wformat=2: YES
Compiler for C supports arguments -w24774: NO
Compiler for C supports arguments -w24777: NO
Compiler for C supports arguments -Wimplicit-fallthrough: YES
Compiler for C supports arguments -Wmaybe-uninitialized: YES
Compiler for C supports arguments -w24701: NO
Compiler for C supports arguments -w24703: NO
Compiler for C supports arguments -Wmissing-attributes: YES
Compiler for C supports arguments -Wmissing-braces: YES
Compiler for C supports arguments -Wno-char-subscripts: YES
Compiler for C supports arguments -Wnull-dereference: YES
Compiler for C supports arguments -Wredundant-decls: YES
Compiler for C supports arguments -Wreturn-type: YES
Compiler for C supports arguments -w24013: NO
Compiler for C supports arguments -Wsequence-point: YES
Compiler for C supports arguments -Wshadow=local: YES
Compiler for C supports arguments -w24456: NO
Compiler for C supports arguments -w24457: NO
Compiler for C supports arguments -Wstrict-aliasing: YES
Compiler for C supports arguments -Wstrict-overflow=3: YES
Compiler for C supports arguments -Wstring-compare: YES
Compiler for C supports arguments -Wstringop-overflow: YES
Compiler for C supports arguments -Wunknown-pragmas: YES
Compiler for C supports arguments -Wunsafe-loop-optimizations: YES
Compiler for C supports arguments -Wunsuffixed-float-constants: YES
Compiler for C supports arguments -Wunused-const-variable=2: YES
Compiler for C supports arguments -w24189: NO
Compiler for C supports arguments -Wunused-local-typedefs: YES
Compiler for C supports arguments -Wunused: YES
Compiler for C supports arguments -w24101: NO
Compiler for C supports arguments -Wvla-parameter: YES
Compiler for C supports arguments -Wvla: YES
Compiler for C supports arguments -Warith-conversion: NO
Compiler for C supports arguments -w24244: NO
Compiler for C supports arguments -Wbad-function-cast: YES
Compiler for C supports arguments -Wcast-function-type: YES
Compiler for C supports arguments -Wcast-qual: YES
Compiler for C supports arguments -Wdangling-else: YES
Compiler for C supports arguments -Wdouble-promotion: YES
Compiler for C supports arguments -Wduplicated-branches: NO
Compiler for C supports arguments -w24754: NO
Compiler for C supports arguments -Wfloat-conversion: YES
Compiler for C supports arguments -Wformat-overflow=2: NO
Compiler for C supports arguments -Wformat-truncation: NO
Compiler for C supports arguments -Wformat=2: YES
Compiler for C supports arguments -w24774: NO
Compiler for C supports arguments -w24777: NO
Compiler for C supports arguments -Wimplicit-fallthrough: YES
Compiler for C supports arguments -Wmaybe-uninitialized: NO
Compiler for C supports arguments -w24701: NO
Compiler for C supports arguments -w24703: NO
Compiler for C supports arguments -Wmissing-attributes: NO
Compiler for C supports arguments -Wmissing-braces: YES
Compiler for C supports arguments -Wno-char-subscripts: YES
Compiler for C supports arguments -Wnull-dereference: YES
Compiler for C supports arguments -Wredundant-decls: YES
Compiler for C supports arguments -Wreturn-type: YES
Compiler for C supports arguments -w24013: NO
Compiler for C supports arguments -Wsequence-point: YES
Compiler for C supports arguments -Wshadow=local: NO
Compiler for C supports arguments -w24456: NO
Compiler for C supports arguments -w24457: NO
Compiler for C supports arguments -Wstrict-aliasing: YES
Compiler for C supports arguments -Wstrict-overflow=3: YES
Compiler for C supports arguments -Wstring-compare: YES
Compiler for C supports arguments -Wstringop-overflow: NO
Compiler for C supports arguments -Wunknown-pragmas: YES
Compiler for C supports arguments -Wunsafe-loop-optimizations: NO
Compiler for C supports arguments -Wunsuffixed-float-constants: NO
Compiler for C supports arguments -Wunused-const-variable=2: NO
Compiler for C supports arguments -w24189: NO
Compiler for C supports arguments -Wunused-local-typedefs: YES
Compiler for C supports arguments -Wunused: YES
Compiler for C supports arguments -w24101: NO
Compiler for C supports arguments -Wvla-parameter: NO
Compiler for C supports arguments -Wvla: YES
Program hexdump found: YES (/usr/bin/hexdump)
Cloning into 'libopencm3'...
remote: Enumerating objects: 1317, done.
remote: Counting objects: 100% (1317/1317), done.
remote: Compressing objects: 100% (1010/1010), done.
remote: Total 1317 (delta 662), reused 476 (delta 274), pack-reused 0 (from 0)
Receiving objects: 100% (1317/1317), 1.19 MiB | 1.38 MiB/s, done.
Resolving deltas: 100% (662/662), done.
Executing subproject libopencm3
libopencm3| Project name: libopencm3
libopencm3| Project version: 0.8.0
libopencm3| C compiler for the host machine: arm-none-eabi-gcc (gcc 13.3.1 "arm-none-eabi-gcc (Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24)) 13.3.1 20240614")
libopencm3| C linker for the host machine: arm-none-eabi-gcc ld.bfd 13.3
libopencm3| C compiler for the build machine: cc (clang 16.0.0 "Apple clang version 16.0.0 (clang-1600.0.26.6)")
libopencm3| C linker for the build machine: cc ld64 1115.7.3
libopencm3| Compiler for C supports arguments -Warith-conversion: YES (cached)
libopencm3| Compiler for C supports arguments -Wbad-function-cast: YES (cached)
libopencm3| Compiler for C supports arguments -Wcast-function-type: YES (cached)
libopencm3| Compiler for C supports arguments -Wdangling-else: YES (cached)
libopencm3| Compiler for C supports arguments -Wdouble-promotion: YES (cached)
libopencm3| Compiler for C supports arguments -Wduplicated-branches: YES (cached)
libopencm3| Compiler for C supports arguments -Wfloat-conversion: YES (cached)
libopencm3| Compiler for C supports arguments -Wformat-overflow=2: YES (cached)
libopencm3| Compiler for C supports arguments -Wformat-signedness: YES
libopencm3| Compiler for C supports arguments -Wformat-truncation: YES (cached)
libopencm3| Compiler for C supports arguments -Wformat=2: YES (cached)
libopencm3| Compiler for C supports arguments -Wimplicit-fallthrough: YES (cached)
libopencm3| Compiler for C supports arguments -Wmaybe-uninitialized: YES (cached)
libopencm3| Compiler for C supports arguments -Wmissing-attributes: YES (cached)
libopencm3| Compiler for C supports arguments -Wmissing-braces: YES (cached)
libopencm3| Compiler for C supports arguments -Wno-char-subscripts: YES (cached)
libopencm3| Compiler for C supports arguments -Wnull-dereference: YES (cached)
libopencm3| Compiler for C supports arguments -Wredundant-decls: YES (cached)
libopencm3| Compiler for C supports arguments -Wreturn-type: YES (cached)
libopencm3| Compiler for C supports arguments -Wsequence-point: YES (cached)
libopencm3| Compiler for C supports arguments -Wshadow=local: YES (cached)
libopencm3| Compiler for C supports arguments -Wstack-protector: YES
libopencm3| Compiler for C supports arguments -Wstrict-aliasing: YES (cached)
libopencm3| Compiler for C supports arguments -Wstrict-overflow=2: YES
libopencm3| Compiler for C supports arguments -Wstring-compare: YES (cached)
libopencm3| Compiler for C supports arguments -Wstringop-overflow: YES (cached)
libopencm3| Compiler for C supports arguments -Wunknown-pragmas: YES (cached)
libopencm3| Compiler for C supports arguments -Wunsafe-loop-optimizations: YES (cached)
libopencm3| Compiler for C supports arguments -Wunsuffixed-float-constants: YES (cached)
libopencm3| Compiler for C supports arguments -Wunused-const-variable=2: YES (cached)
libopencm3| Compiler for C supports arguments -Wunused-local-typedefs: YES (cached)
libopencm3| Compiler for C supports arguments -Wunused: YES (cached)
libopencm3| Compiler for C supports arguments -Wvla-parameter: YES (cached)
libopencm3| Program python3 found: YES (/opt/homebrew/opt/[email protected]/bin/python3.12)
libopencm3| Build targets in project: 21
libopencm3| Subproject libopencm3 finished.
Dependency opencm3_stm32f0 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f1 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f1 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f3 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f4 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f4 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f7 found: YES 0.8.0 (overridden)
Dependency opencm3_stm32f7 found: YES 0.8.0 (overridden)
Dependency opencm3_lm4f found: YES 0.8.0 (overridden)
Fetching value of define "_MSC_VER" : (undefined)
Found pkg-config: YES (/opt/homebrew/bin/pkg-config) 2.3.0
Build-time dependency libusb-1.0 found: YES 1.0.27
Build-time dependency libftdi1 found: YES 1.5
Build-time dependency hidapi found: YES 0.14.0
Compiler for C supports arguments -DCONFIG_BMDA=1: YES
Compiler for C supports arguments -DHOSTED_BMP_ONLY=0: YES
Compiler for C supports arguments -Wno-format-nonliteral: YES
Compiler for C supports arguments -Wno-missing-field-initializers: YES
Message: Adding targets for Black Magic Firmware
Program arm-none-eabi-size found: YES
Program arm-none-eabi-objcopy found: YES
Message: Adding targets for Black Magic Firmware Bootloader
Program bmputil found: NO
Build targets in project: 36
Black Magic Debug 1.10.0
Remote Protocol
RISC-V acceleration : NO
Targets
Cortex-A/R support : NO
Cortex-M support : NO
RISC-V 32-bit support : NO
RISC-V 64-bit support : NO
Arterytek parts : NO
Ambiq Apollo3 parts : NO
WinChipHead CH32 parts : NO
WinChipHead CH579 parts : NO
Energy Micro parts : NO
GigaDevice parts : NO
HC32 parts : NO
LPC series parts : NO
MindMotion parts : NO
nRF series parts : NO
Kinetis series parts : NO
Puya PY32 series parts : NO
Renesas parts : NO
Raspberry Pi MCUs (RP2040, RP2350): NO
ATSAM series parts : NO
STM32 (and clones) parts : YES
Texas Instruments parts : NO
Xilinx parts : NO
Probe
Name : ST-Link
Platform : STM32F1
Bootloader : Black Magic Debug Bootloader
Load Address : 0x8002000
SWIM as UART : NO
Black Magic Debug
Debug output : NO
RTT support : NO
Advertise QStartNoAckMode : NO
Building Firmware : YES
Building BMDA : YES
Subprojects
libopencm3 : YES
User defined options
Cross files : cross-file/arm-none-eabi.ini
cross-file/stlink.ini
bmd_bootloader : true
probe : stlink
rtt_support : false
targets : stm
Found ninja-1.12.1 at /opt/homebrew/bin/ninja
(base) macos@Eka-MacBook-Pro blackmagic % ninja -C build -j$(nproc)
ninja: Entering directory `build'
[10/543] Linking target src/target/flashstub/rp_stub
Memory region Used Size Region Size %age Used
sram: 260 B 4 KB 6.35%
[11/543] Linking target src/target/flashstub/lmi_stub
Memory region Used Size Region Size %age Used
sram: 48 B 1 KB 4.69%
[12/543] Linking target src/target/flashstub/efm32_stub
Memory region Used Size Region Size %age Used
sram: 80 B 1 KB 7.81%
[417/543] Linking target blackmagic_stlink_firmware.elf
Memory region Used Size Region Size %age Used
rom: 86312 B 128 KB 65.85%
ram: 7928 B 20 KB 38.71%
[483/543] Compiling C object blackmagic.p/src_target_rp2040.c.o
../src/target/rp2040.c:727:22: warning: cast from 'void (*)(adiv5_access_port_s *)' (aka 'void (*)(struct adiv5_access_port *)') to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict]
727 | target->priv_free = (void (*)(void *))adiv5_ap_unref;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
[543/543] Linking target blackmagic
(base) macos@Eka-MacBook-Pro blackmagic % ninja -C build boot-bin boot-elf
ninja: Entering directory `build'
[6/7] Linking target blackmagic_stlink_bootloader.elf
Memory region Used Size Region Size %age Used
rom: 7788 B 128 KB 5.94%
ram: 6548 B 20 KB 31.97%
[7/7] Generating blackmagic_stlink_bootloader.bin with a custom command
(base) macos@Eka-MacBook-Pro blackmagic %
(base) macos@Eka-MacBook-Pro blackmagic % st-flash erase
st-flash 1.8.0
2024-12-21T12:18:06 INFO common.c: STM32F1xx_MD: 20 KiB SRAM, 128 KiB flash in at least 1 KiB pages.
Mass erasing...
Mass erase completed successfully.
2024-12-21T12:18:06 INFO common.c: NRST is not connected --> using software reset via AIRCR
(base) macos@Eka-MacBook-Pro blackmagic % st-flash write build/blackmagic_stlink_bootloader.bin 0x08000000
st-flash 1.8.0
2024-12-21T12:18:19 INFO common.c: STM32F1xx_MD: 20 KiB SRAM, 128 KiB flash in at least 1 KiB pages.
file build/blackmagic_stlink_bootloader.bin md5 checksum: 4ff8c515e0f1e9b860d9f4b27b80a2cd, stlink checksum: 0x000b4d64
2024-12-21T12:18:19 INFO common_flash.c: Attempting to write 7788 (0x1e6c) bytes to stm32 address: 134217728 (0x8000000)
-> Flash page at 0x8001c00 erased (size: 0x400)
2024-12-21T12:18:19 INFO flash_loader.c: Starting Flash write for VL/F0/F3/F1_XL
2024-12-21T12:18:19 INFO flash_loader.c: Successfully loaded flash loader in sram
2024-12-21T12:18:19 INFO flash_loader.c: Clear DFSR
2024-12-21T12:18:19 INFO flash_loader.c: Clear CFSR
2024-12-21T12:18:19 INFO flash_loader.c: Clear HFSR
8/8 pages written
2024-12-21T12:18:20 INFO common_flash.c: Starting verification of write complete
2024-12-21T12:18:20 INFO common_flash.c: Flash written and verified! jolly good!
(base) macos@Eka-MacBook-Pro blackmagic % st-flash write build/blackmagic_stlink_firmware.bin 0x08002000
st-flash 1.8.0
2024-12-21T12:18:40 INFO common.c: STM32F1xx_MD: 20 KiB SRAM, 128 KiB flash in at least 1 KiB pages.
file build/blackmagic_stlink_firmware.bin md5 checksum: 639c1faf1f70ad561f2ba61631f6697c, stlink checksum: 0x0077aecc
2024-12-21T12:18:40 INFO common_flash.c: Attempting to write 78120 (0x13128) bytes to stm32 address: 134225920 (0x8002000)
-> Flash page at 0x8015000 erased (size: 0x400)
2024-12-21T12:18:42 INFO flash_loader.c: Starting Flash write for VL/F0/F3/F1_XL
2024-12-21T12:18:42 INFO flash_loader.c: Successfully loaded flash loader in sram
2024-12-21T12:18:42 INFO flash_loader.c: Clear DFSR
2024-12-21T12:18:42 INFO flash_loader.c: Clear CFSR
77/77 pages written
2024-12-21T12:18:46 INFO common_flash.c: Starting verification of write complete
2024-12-21T12:18:47 INFO common_flash.c: Flash written and verified! jolly good!
You can use lsusb to list Black Magic Probe
(base) macos@Eka-MacBook-Pro blackmagic % lsusb
...
Bus 000 Device 006: ID 1d50:6018 1d50 Black Magic Probe (ST-Link/v2) v1.10.0-1591-gc37a38e4 Serial: 76764ECC
...
You should have 2x USB CDC ACM devices
(base) macos@Eka-MacBook-Pro blackmagic % ls /dev/tty.usbmodem*
/dev/tty.usbmodem76764ECC1 /dev/tty.usbmodem76764ECC3
(base) macos@Eka-MacBook-Pro blackmagic %
You can also use blackmagic
to test real quick with no target
(base) macos@Eka-MacBook-Pro blackmagic % ./build/blackmagic -t
Black Magic Debug App v1.10.0-1591-gc37a38e4
for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, J-Link and FTDI (MPSSE)
Using 1d50:6018 76764ECC Black Magic Debug
Black Magic Probe (ST-Link/v2) v1.10.0-1591-gc37a38e4
Running in Test Mode
Target voltage: 3.23V
Speed set to 6.000MHz for SWD
Switching from JTAG to dormant
Switching out of dormant state into SWD
Deprecated JTAG to SWD sequence
No usable DP found
No target found
When you plug in any ARM Cortex MCU as target (I used STM32 BluePill), the Black Magic probe should be able to communicate to the target
(base) macos@Eka-MacBook-Pro blackmagic % ./build/blackmagic -t
Black Magic Debug App v1.10.0-1591-gc37a38e4
for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, J-Link and FTDI (MPSSE)
Using 1d50:6018 76764ECC Black Magic Debug
Black Magic Probe (ST-Link/v2) v1.10.0-1591-gc37a38e4
Running in Test Mode
Target voltage: 3.23V
Speed set to 6.000MHz for SWD
Switching from JTAG to dormant
Switching out of dormant state into SWD
Deprecated JTAG to SWD sequence
DP DPIDR 0x1ba01477 (v1 rev1) designer 0x43b partno 0xba
AP 0: IDR=14770011 CFG=00000000 BASE=e00ff000 CSW=e3000040 (AHB3-AP var1 rev1)
Halt via DHCSR(00030003): success after 20ms
ROM Table: BASE=0xe00ff000 SYSMEM=1, Manufacturer 020 Partno 410 (PIDR = 0x00000a0410)
0 0x0e000e000: Generic IP component - Cortex-M3 SCS (System Control Space) (PIDR = 0x04001bb000 DEVTYPE = 0x00 ARCHID = 0x0000)
-> cortexm_probe
CPUID 0x411fc231 (M3 var 1 rev 1)
1 0x0e0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x04001bb002 DEVTYPE = 0x00 ARCHID = 0x0000)
2 0x0e0002000: Generic IP component - Cortex-M3 FBP (Flash Patch and Breakpoint) (PIDR = 0x04000bb003 DEVTYPE = 0x00 ARCHID = 0x0000)
3 0x0e0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x04001bb001 DEVTYPE = 0x00 ARCHID = 0x0000)
4 0x0e0040000: Debug component - Cortex-M3 TPIU (Trace Port Interface Unit) (PIDR = 0x04001bb923 DEVTYPE = 0x11 ARCHID = 0x0000)
5 Entry 0xfff42002 -> Not present
ROM Table: END
*** 1 STM32F1 L/M density M3
RAM Start: 0x20000000 length = 0x5000
Flash Start: 0x08000000 length = 0x20000 blocksize 0x400
Now you can use Black Magic Probe for debugging and programming.