PlatformIO Community

STM32F1 Blue Pill stuck in DFU mode after upload


I’ve been trying to get my STM32F103C Blue Pill to run code from PIO for a little while now. I have it configured with the Maple Labs firmware so it can be programmed via the Arduino IDE over it’s MicroUSB port.

I’ve tried to use the following board targets to upload to it to no avail:

platform = ststm32
framework = arduino
board = bluepill_f103c8_128k
upload_protocol = dfu
; board_build.variant = BLUEPILL_F103XX

platform = ststm32
framework = arduino
board = bluepill_f103c8
upload_protocol = dfu
; board_build.variant = BLUEPILL_F103XX

If I uncomment the two lines, then the build fails, citing duplicate function definitions in the framework header files. With the two lines commented, the build succeeds, but then fails to get code to run as it gets the board stuck in DFU mode, not unlike this here: (Can not upload to Blue Pill using dfu) I’m at a loss for what to do.

Can not upload to Blue Pill using dfu

Try adding board_build.core = maple so it uses the older core. I wrote board_builds.variant in the other thread without reading the docs on this properly, and realising it was was .core. not .variants :wink:


Does not change the behavior.

platform = ststm32
framework = arduino
board = bluepill_f103c8_128k
upload_protocol = dfu
; board_build.variant = BLUEPILL_F103XX
board_build.core = maple

platform = ststm32
framework = arduino
board = bluepill_f103c8
upload_protocol = dfu
; board_build.variant = BLUEPILL_F103XX
board_build.core = maple

Upload Output:

Processing bluepill_f103c8_128k (platform: ststm32; board: bluepill_f103c8_128k; framework: arduino)
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: ST STM32 > BluePill F103C8 (128k)
HARDWARE: STM32F103C8T6 72MHz 20KB RAM (128KB Flash)
DEBUG: CURRENT(stlink) EXTERNAL(blackmagic, jlink, stlink)
Library Dependency Finder ->
Collected 9 compatible libraries
Scanning dependencies...
No dependencies
Checking size .pioenvs\bluepill_f103c8_128k\firmware.elf
Memory Usage ->
DATA:    [          ]   3.8% (used 768 bytes from 20480 bytes)
PROGRAM: [=         ]  10.7% (used 13976 bytes from 131072 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, dfu, jlink, mbed, stlink
CURRENT: upload_protocol = dfu
Looking for upload port...
Auto-detected: COM6
Uploading .pioenvs\bluepill_f103c8_128k\firmware.bin
maple_loader v0.1
Resetting to bootloader via DTR pulse
Searching for DFU device [1EAF:0003]...
Found it!

Opening USB Device 0x1eaf:0x0003...
Found Runtime: [0x1eaf:0x0003] devnum=1, cfg=0, intf=0, alt=2, name="STM32duino bootloader v1.0  Upload to Flash 0x8002000"
Setting Configuration 1...
Claiming USB DFU Interface...
Setting Alternate Setting ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
Transfer Size = 0x0400
Starting download: [##################################################] finished!
error resetting after download: usb_reset: could not reset device, win error: The system cannot find the file specified.

state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present

Resetting USB to switch back to runtime mode

The board still gets stuck in DFU mode.


This worked for me…

platform = ststm32
framework = arduino
board = genericSTM32F103C8
upload_protocol = dfu

My success rate was the same as yours. There is no need to specify the board_build.core parameter with the genericSTM32F103C8 board type (yet) as it currently defaults to the maple core. But it won’t hurt to specify it if you wish.


I’m linking the verbose upload output for each environment incase anyone more familar with pio and the stm32 guts can see what’s happening. My interpretation is that the STM32 environment is missing ‘something’ as the firmware is a lot smaller… but the other two are almost the same size, but I would have expected them to be identical or nearly identical? It also begs the question of should pio be reporting success when the upload actually failed as the board didn’t report successful reset? If it can detect that failure, anyway - otherwise it’s an issue worth mentioning in the docs.

fail - bluepill_f103c8-stm32
fail - bluepill_f103c8-maple
success - genericSTM32F103C8


Huh. New issue now with your config, this time in build.

Compiling .pioenvs\genericSTM32F103C8\FrameworkArduino\wiring_time.c.o
Archiving .pioenvs\genericSTM32F103C8\libFrameworkArduino.a
Indexing .pioenvs\genericSTM32F103C8\libFrameworkArduino.a
Linking .pioenvs\genericSTM32F103C8\firmware.elf
c:/users/neilb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.exe: .pioenvs\genericSTM32F103C8\libFrameworkArduino.a(syscalls.c.o): in function `_sbrk':
syscalls.c:(.text._sbrk+0x38): undefined reference to `_Min_Stack_Size'
c:/users/neilb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.exe: .pioenvs\genericSTM32F103C8\libFrameworkArduino.a(syscalls.c.o):(.data.heap_end.7830+0x0): undefined reference to `_end'
collect2.exe: error: ld returned 1 exit status
*** [.pioenvs\genericSTM32F103C8\firmware.elf] Error 1


I’d do a pio platform uninstall ststm32 (and also any other fixed-version ststm32 packages you have installed, look it up via pio platform list) and pio platform install ststm32 to ensure you have the latest version.


Where can I use those commands? cmd doesn’t recognise pio.


Open a terminal in VSCode then


What? What kind of terminal? Neither cmd, powershell, nor WSL recognizes a pio command. Please be more specific.


Are you using PIO from the commandline or VSCode?


How does it matter? The vscode terminal is WSL.


Clicking the terminal as I’ve linked above will give you a shell which has the proper PATH environment variable set up.


If you run from your ‘normal’ command prompt, and your search %PATH% isn’t set up right so that pio can be found, it won’t work… hence why if you’re using VSCode… just click that last icon that looks a bit like a command prompt, so you get a properly configured terminal to then run any of the pio commands… :wink:


So I see. The terminal never opens though…


I don’t know if it has the same effect, but I went into the PIO Home page and reinstalled the STstm32 platform.


Ah. The re installation worked. Stuff compiles now, and I now have a new issue! :slight_smile:


lol… unfortunately, it actually does, but due to a glitch in vscode (which should be fixed in the 1.32 (EDIT: nope, still playing up in 1.32.1 :tired_face: ) that was released today or yesterday, you can’t see the prompt at first… if you click on the terminal area though, and start typing, it will work… can probably just hit enter for a new line and it should work.

EDIT: Yeah, pressing enter after ensuring the terminal has input focus is enough to liven it into being visible… or you can …

New issue… that’s progress at least! :smiley:


pfeerick Out of curiosity, do you have a solution for how to adapt the generic STM32F103 build target to make use of the full 128K flash on the chip? I’m pretty sure I have that version of the Blue Pill.

The target that we’ve established to work only allows the program memory to rise to 65,536B.

The DFU features on the stm32duino framework appear to be a ways away from being merged. :slight_smile:


Only a guess atm…

The linker script that bluepill_f103c8.json sets the flash memory size, and bluepill_f103c8_128k.json does not have a valid linker file at present. I do however suspect after a quick look at the stm32duino to so how they account for 64K and 128K that a valid version of the linker file just needs to be changed to specify 128K, instead of 64K as it currently does. i.e, a copy of this file, and the relevant changes made to the 128k json file to point to a new linker file, and the relevant line changed there.

However, when I tried exactly that, I got a Warning! Cannot find linker script for the current target! and the compiler now has stage fright, so I got no idea what I missed editing there… I thought it was a matter of ‘create missing linker file with minor change, update path to it in board json, job done’ … but no, it wants to be … DIFFICULT!

Not to be dissuaded, I decided to go about it entirely the wrong way, and edited stm32f103x8.ld so that it said FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K on line 4, and line 55 of bluepill_f103c8.json to read "maximum_size": 131072, … and well, yes, it did compile and say the right things… but that was entirely the wrong way to do it! :open_mouth:

btw, there is no reason you couldn’t do the same to genericSTM32F103C8.json … I just happened to be poking around in the bluepill_f103c8.json. But the real question would be… does it blend… er, sorry… does it still work!?

PS: these files are located in %userprofile%\.platformio\platforms\ststm32\



HRM! That does indeed work, nicely done! :smile: I suppose that does confirm once and for all that my board has the 128K flash size.

I believe my next question is rather obvious. How can we get a more formal version of this mod integrated into the ststm32 platform? I suppose I don’t understand how the confluence of my usage circumstances has affected the way that PIO STM32 support normally works.

From what I understand, the only “non-stock” modification I’ve made to the platform is to use the maple core and use a “generic” build target spec. (not including the mod we just made to the linker script. :wink:)