IDing STM32 Clones, and Setting Up a Black Magic Probe

For my blinky++ project, I needed a debug probe to interface with the SAM D21 that the design centers around. There’s a lot of options in this space - Microchip has a few of their own debug probes, and there’s also vendor-independent debug probes like J-Link and I-jet. I also came across the Black Magic Probe, an open-source vendor-independent debug probe based around the STM32F103. What really sold me on this option was the fact that you can convert STM32 Blue Pills to Black Magic Probes, which can be had for $8 or less.

BOOT0 not pulling up enough

I got my STM32 Blue Pill in the mail and went to flash it with the BMP firmware. The first step is to build the firmware - use make PROBE_HOST=swlink to target the Blue Pill. The next step is then to flash the DFU bootloader via UART, and then flash the application code via either UART or DFU.

When I went to flash the bootloader via UART, I couldn’t communicate with the STM32. I noticed that with the BOOT0 jumper pulled high, which should force the STM32 to boot from the built-in bootloader in system memory instead of the internal flash, the board was still running its default blink program. I did some googling and found this EEVblog thread that mentioned BOOT0 on some Blue Pills not going over the threshold voltage when pulled up. I probed my BOOT0 pin and, sure enough, it was measuring 0.92 V instead of the expected 3.3V.

I fixed this by removing the R3 resistor and shorting across its pads. After this rework, the MCU correctly booted from system memory and allowed me to successfully flash the bootloader via UART with stm32loader (sudo python2 stm32loader.py -p /dev/ttyUSB0 -e -w -v blackmagic_dfu.bin)

R3 removed, pads shorted

Application Code Failing to Flash

The next step was to flash the application code.

Trying to flash via UART

sudo python2 stm32loader.py -p /dev/ttyUSB0 -e -w -v -a "0x08002000" blackmagic.bin 2>&1 | tee flash.log

Verification FAILED
98648 vs 98648
0x82c: 0xea vs 0x0
0x82d: 0xfa vs 0x0
0x11ac: 0x1 vs 0x0
...
0x18107: 0x8 vs 0x63

Trying to flash via dfu_util

sudo dfu-util -d 1d50:6018,:6017 -s 0x08002000:leave -D blackmagic.bin

Downloading element to address = 0x08002000, size = 98648
Erase   	[=========================] 100%        98648 bytes
Erase    done.
Download	[==============           ]  56%        55296 bytesdfu-util: Error during download get_status

and with verbose (-v) enabled:

...
 Download from image offset 0000e000 to memory 08010000-080103ff, size 1024
 Download from image offset 0000e400 to memory 08010400-080107ff, size 1024
dfu-util: Error during download get_status

Realizing it’s a Clone

Note that the flash fails at 0x08010000 - e.g. right at the start of the upper 64k sector of flash. No matter how many times I tried to flash, it always failed at this point.

So, why is this an issue? Genuine STM32F103C8’s only advertise 64k of flash, but they let you flash up to 128k (this is due to -C8’s likely being binned versions of -CB’s). Many F103-based projects, including Black Magic Probe, rely on this unadvertised flash to work. Even though this upper sector of flash occasionally has some bad blocks on C8’s, it will successfully flash most of the sector. On my board, it wasn’t letting me flash any of this upper sector. This led me to believe that this chip really did only have 64k of flash, indicating that it’s a fake or clone.

The markings on the chip also looked off, esp. the ST Logo.

Comparison of a clone STM32 to a legitimate STM32.  Note the differences in the ST logo.

Okay, so it looks like it’s probably a clone… Can we verify that?

Yes! The Bluepill Diagnostics project is a piece of firmware for the STM32F103 that can verify if the chip is legitimate by leveraging some known silicon errata of genuine chips. Flash it to the Blue Pill (I flashed via UART), then connect to the Blue Pill over USB via a serial terminal. See Bluepill Diagnostic’s website for more detailed instructions.

Bluepill Diagnostics Results

a - STM32F103C8T6 Authenticity test, don't use with SWD/JTAG. Requires test h once to complete:

STM32F103C8 authentication FAILED one or more tests:
----------------------------------------------------
PASS - Declared flash = 65536 Bytes
FAIL - DBGMCU_IDCODE is readable with no SWD/Jtag connected
FAIL - Second 64KB flash block not verified or not tested
FAIL - JDEC manufacturer id NOT STMicroelectronics

j - Jdec manufacturer id:

Jdec Continuation Code: 0x04
Jdec Identity Code: 0x3B
JDEC manufacturer id: CKS or APM 

These results confirm that the STM32 on the Blue Pill I received is a clone!

Finding a Blue Pill with a Genuine STM32

I wanted to verify that the STM32 clone was the cause of my flashing issue, so I took to trying to find a Blue Pill with a genuine STM32. I ended up going to eBay - my thinking was that since clones have ramped up over the years, a used Blue Pill from a few years ago would have a better chance of having a genuine chip. I found a used Blue Pill, and I got lucky - I tested it with Bluepill Diagnostics, and it tested as a genuine STM32. I was able to write to the full 128k of flash, and I was able to successfully flash it with the BMP firmware using the same process that failed on the clone. I also didn’t need to perform the BOOT0 rework on this one, showing that the 100k pull-up on BOOT0 works on legit STM32F103 silicon but isn’t compatible with the silicon in clones, maybe due to internal pull-up differences.

Closing Thoughts

Black Magic Probe is a great project that opens up professional debugging features at an extremely low-cost, without any of the licensing restrictions offered by other low-cost options like the J-Link EDU. I’d recommend this as a debugger option, but I’d also strongly recommend that you buy a board with an F103 directly from ST instead of a Blue Pill. Some options include the ST-Link v2/v2.1/v3 and most Nucleo boards, all of which can be had for $10-35 at the time of writing.

Written on September 18, 2021