November 20, 2020

Black Pill boards - first impressions

My black pills just arrived and the chips are indeed marked STM32F411CEU6. I ordered 10 of them for $43.00 (including shipping), so each board cost me just under $5.00. I placed the order October 29, and they arrived November 20, so the shipping time was 3 weeks.

The first important thing to note is that the SWD connector has the pins reversed compared to a blue pill board. So if you just hook up your ST-Link without paying attention, power and ground are reversed and you just wasted $5.00. I am proud to say I did not do this, but it will take care to avoid it in the future as I often work with both boards.

Power it up via the ST-Link

With the ST-Link properly connected, a red power LED comes on, and a blue LED pulses in a "breathing" fashion, so whatever test code is loaded is using PWM to drive the LED.

I fire up openocd just as it it was connected to a blue pill and see:

warn : UNEXPECTED idcode: 0x2ba01477
Error: expected 1 of 1: 0x1ba01477
Getting an IDCODE mismatch certainly makes sense. Strangely though this is the same IDcode as for the "other" kind of STM32F103 that I now use the file cs32f1x.cfg to handle.

But when I look at the file stm32f4x.cfg, it contains 0x2ba01477, so apparently this is OK.

Using openocd

I put the following line in a shell script that I name "ocd":
openocd -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg
Then in a window I dedicate to this purpose, I type "./ocd" to run the above script.

Then in another window, I type:

telnet localhost 4444
This gives me a prompt from openocd and I can type commands. This is how you do things with openocd.
I halt the processor using:
Open On-Chip Debugger
reset halt
adapter speed: 2000 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000238 msp: 0x200006a0
Since I have halted the processor, the blue status light is no longer blinking.
Typing "reset run" sets the chip running again.
I dump the first 128K of flash using this:
dump_image dump.bin 0x08000000 0x20000
dumped 131072 bytes in 2.538966s (50.414 KiB/s)

Looking at the file "dump.bin", most of it is 0xff, but there clearly is a program from 0x0 to 0x98c -- about 2432 bytes in size, round up to 0xa00 (2560 bytes). So I dump only the interesting portion using this:

dump_image blink.bin 0x08000000 0xa00
dumped 2560 bytes in 0.047838s (52.260 KiB/s)

I try the following to see if I can read 512K of flash (and I can).

dump_image hog.bin 0x08000000 0x80000
dumped 524288 bytes in 10.161884s (50.384 KiB/s)

We can dump the 128K of sram as follows:

dump_image sram.bin 0x20000000 0x20000
dumped 131072 bytes in 2.461606s (51.999 KiB/s)

We can dump system memory (the boot loader) like this:

dump_image bootloader.bin 0x1fff0000 0x8000
dumped 32768 bytes in 0.620546s (51.567 KiB/s)
Looking at a hex dump of this, it does look entirely reasonable.

Do we really have 512K of flash?

I write a little python script to generate a 512K file with consecutive 4 byte numbers. I write this to flash as follows:
flash write_image erase bogus.bin 0x08000000
auto erase enabled
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000046 msp: 0x200006a0
wrote 524288 bytes from file bogus.bin in 17.522072s (29.220 KiB/s)
I can examine memory as follows:
mdw 0x08000000 16
0x08000000: 00000000 00000001 00000002 00000003 00000004 00000005 00000006 00000007
0x08000020: 00000008 00000009 0000000a 0000000b 0000000c 0000000d 0000000e 0000000f

mdw 0x0807ff00 64
0x0807ff00: 0001ffc0 0001ffc1 0001ffc2 0001ffc3 0001ffc4 0001ffc5 0001ffc6 0001ffc7
0x0807ff20: 0001ffc8 0001ffc9 0001ffca 0001ffcb 0001ffcc 0001ffcd 0001ffce 0001ffcf
0x0807ff40: 0001ffd0 0001ffd1 0001ffd2 0001ffd3 0001ffd4 0001ffd5 0001ffd6 0001ffd7
0x0807ff60: 0001ffd8 0001ffd9 0001ffda 0001ffdb 0001ffdc 0001ffdd 0001ffde 0001ffdf
0x0807ff80: 0001ffe0 0001ffe1 0001ffe2 0001ffe3 0001ffe4 0001ffe5 0001ffe6 0001ffe7
0x0807ffa0: 0001ffe8 0001ffe9 0001ffea 0001ffeb 0001ffec 0001ffed 0001ffee 0001ffef
0x0807ffc0: 0001fff0 0001fff1 0001fff2 0001fff3 0001fff4 0001fff5 0001fff6 0001fff7
0x0807ffe0: 0001fff8 0001fff9 0001fffa 0001fffb 0001fffc 0001fffd 0001fffe 0001ffff

This all looks great, but can we verify this using openocd? Indeed we can, as follows.

verify_image bogus.bin 0x08000000
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0x200006a0
verified 524288 bytes in 3.869881s (132.304 KiB/s)
So, we really do have 512K of flash. Amazing! Now let's put the blink demo back. The following works, but leaves lots of flash full of the test data.
flash write_image erase blink.bin 0x08000000
auto erase enabled
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000046 msp: 00000000
wrote 16384 bytes from file blink.bin in 0.721685s (22.170 KiB/s)

Memory map

This is in section 5 of the datasheet (not reference manual). Any of the above 3 can be aliased to 0x0 by use of the BOOT jumpers.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org