Do I really need to put stm32 microcontroller into bootloader mode to program it?

I have started learning stm32 microcontroller for a while using a very small development board "stm32f103c8t6" (or blue pill). when I started, I learnt from some tutorials that I have to switch a jumper in order to program it.

(The photo is a screenshot taken from a random tutorial, but every tutorial I have watched also said that)

The jumper - as far as I know - only changes the boot mode of the processor to load from the system memory(the bootloader) which only takes effect if I restart the board to starting booting from there.

I don't know how is that supposed to be a "programming mode" as I'm using an external st-link programmer that uses SWD.

So my question here , Is there really such a thing called "programming mode" ? and if so, How exactly does it work ?

Also it's worth mentioning that I've just tried to program it and the program worked as it's supposed to (I hope I haven't screwed anything up :d ).

You only need to put the microcontroller into bootloader mode if you're going to program it over the UART, using the bootloader.

Generally speaking, you can program the microcontroller over SWD at any time.

The primary exceptions are if the microcontroller is running a program that disables SWD by setting a SWJ_CFG bit in AFIO->MAPR (e.g, to use the associated pins as GPIOs), or if the MCU is running in low-power modes without the appropriate DBGMCU flags set to keep the debug interface active in those modes. If any of these are the case, putting the microcontroller into bootloader mode is an easy workaround, as the SWD interface is active (and sleep modes are not used) while the bootloader is running.

• You don't even need play with the BOOT0/1 pins to do that. I've successfully rebooted to the ROM bootloader on several STM32 families through some careful coding. The BOOT pins are handy but not absolutely necessary. – akohlsmith Oct 27 '17 at 21:41
• Note also that the ROM bootloader supports several types of interfaces, not just UART. Though while the 103 has USB, that is not one of the interfaces supported by the ROM bootloader. On later STM32 variants it is. – Chris Stratton Oct 27 '17 at 21:54
• @ChrisStratton It's not necessarily quite as simple as "later" variants, but you're essentially correct. ST Application Note AN2606 has a lengthy rundown of which STM32 parts have which bootloaders, and which features are supported. – duskwuff Oct 27 '17 at 22:22
• @akohlsmith which is not a rocket science (6-7 lines of code to invoke). But internal bootloader is a bit useless as it does not check if if the image is correct, does not provide any decryption of the loaded image and does not work if you protect the memory. I use in the production devices my own ones - writing them is quite straightforward and easy. – P__J__ Oct 28 '17 at 19:04

There are possibly many ways to program the board, using different tools. One of them, which seems quite easy is to use the ST-Link V2 (google it) and OpenOCD.

1. Leave both boot jumpers to "0". Connect SWDIO, SWCLK, GND pins to the appropriate pins of the ST Link. Apply power to the board paying attention to whether it is 5V or 3.3V. The ST-Link conveniently has a 3.3V output that can be used. Since the board receives 5V from the USB connector, do not connect other power pins at the same time with the USB port. It may be useful to have a cable with 4 terminals on the ST-Link side and split 3+1 terminals on the board side. The board should light up one LED and may start blinking with the other one, if it's programmed.

2. Have OpenOCD installed, more recent versions may be less buggy (e.g. at least 0.9.x or better 0.10.x). Older versions, such that included in Linux distributions, may have issues with e.g. reset configuration and require fiddling with config files.

3. [optional] If you run Linux and are not comfortable with running OpenOCD as root, create a file in /etc/udev/rules.d with the following content:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="0664", GROUP="stlink"


This will allow members of the stlink group to access the ST-Link device. Create this group and add yourself to it. You may use whatever group that is convenient.

1. Assuming a Linux host and system-wide default OpenOCD installation, check if connectivity is okay, the MCU is alive, and OpenOCD can talk to it:

 openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg


Depending on the OpenOCD version, the following may also work:

     openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg


If things are good, OpenOCD will print some information about the MCU (voltage, number of HW breakpoints, etc) and keep running.

1. It may be possible to run OpenOCD as a daemon and use telnet to use it, but I think it is more convenient to start it every time. Assuming you have a properly compiled binary, let's say, blinky.bin, you can program it into the MCU with the following script:

OPENOCD="openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg"
\$OPENOCD -c "init" -c "reset halt" -c "stm32f1x mass_erase 0" -c "flash write_bank 0 blinky.bin 0" -c "reset run" -c "shutdown"


Note that there is the file name inside this script that you will need to adjust. It is probably a good idea to start with something really simple.

The above mainly assumes Linux as a host, but the steps should be conceptually similar in Windows, after installing drivers and making adjustments to how things are installed, like paths and so on.

If you're using an ST-Link (SWD) programmer, then you don't need to put the board into "programming mode".

A bootloader is what allows the chip to "download" and run a new program. The "programming mode" jumper uses the BOOT pins to signal to the ROM bootloader that it needs to get ready to download a new program, otherwise the chip will start running the program that is already in memory. Since you're using SWD for programming, the ROM bootloader is not needed.

: as Chris Stratton and duskwuff point out below, the STM32F103 ROM bootloader does not support programming through USB, only UART, and it cannot be erased. There is a separate user flash bootloader that can be loaded onto the board that does support programming over USB (i.e. for use with Arduino IDE), but it does not use the BOOT pins (so is not affected by the "programming mode" jumper).

• The bootloader involved here is in ROM (or, at least, non-user-modifiable flash). It's separate from the user flash, and cannot be erased over SWD. – duskwuff Oct 27 '17 at 20:13
• @duskwuff, thanks for the correction! I was thinking of a different chip. – youtooth Oct 27 '17 at 20:16
• This is incorrect - the factory ROM bootloader on the STM32F103 does not support USB, although that on many later STM32 varients does. Thus any functional USB bootloader for the 103 would have to be resident in application flash rather than ROM, and therefore to enter it, the boot pins would be set for a normal flash boot, not a ROM bootloader boot. – Chris Stratton Oct 27 '17 at 21:56
• @ChrisStratton, thanks for the correction! Apparently I've only used STM32 parts that supported USB/DFU for the factory bootloader, so I wasn't aware that it wasn't supported on this chip. – youtooth Oct 31 '17 at 19:22
• "only UART" is not correct either - it supports a range of interfaces, just not (on the `103) USB. – Chris Stratton Oct 31 '17 at 22:05