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.

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

enter image description here

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.

enter image description here

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 ).


4 Answers 4


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.

  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – akohlsmith
    Oct 27, 2017 at 21:41
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Oct 27, 2017 at 21:54
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – user39382
    Oct 27, 2017 at 22:22
  • \$\begingroup\$ @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. \$\endgroup\$ Oct 28, 2017 at 19:04
  • \$\begingroup\$ @duskwuff-inactive- after power up, does this boot loader waits for a program via UART forever? or does it check for program and continues executing the existing code? \$\endgroup\$ Jun 28, 2020 at 9:56

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.

[edit]: 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).

  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – user39382
    Oct 27, 2017 at 20:13
  • \$\begingroup\$ @duskwuff, thanks for the correction! I was thinking of a different chip. \$\endgroup\$
    – youtooth
    Oct 27, 2017 at 20:16
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Oct 27, 2017 at 21:56
  • \$\begingroup\$ @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. \$\endgroup\$
    – youtooth
    Oct 31, 2017 at 19:22
  • \$\begingroup\$ "only UART" is not correct either - it supports a range of interfaces, just not (on the `103) USB. \$\endgroup\$ Oct 31, 2017 at 22:05

From the Product Specifications datasheet DS5319 PDF, Rev 17 (dated August 2015), Section 2.3.8, Boot modes:

At startup, boot pins are used to select one of three boot options:

  • Boot from User Flash
  • Boot from System Memory
  • Boot from embedded SRAM

The boot loader is located in System Memory. It is used to reprogram the Flash memory by using USART1. For further details please refer to AN2606.

From the introduction of AN2606 PDF (rev 42, dated Dec 2019): "The bootloader is stored in the internal boot ROM memory (system memory) of STM32 devices. It is programmed by ST during production. Its main task is to download the application program to the internal Flash memory through one of the available serial peripherals (USART, CAN, USB, I2C, SPI, etc.). A communication protocol is defined for each serial interface, with a compatible command set and sequences. This document applies to the products listed in Table 1. They are referred as STM32 throughout the document."

The chapter on the STM32F10xxx devices bootloader says "Once initialized, the USART1 configuration is: 8 bits, even parity and 1 Stop bit." "PA10 pin: USART1 in reception mode", "PA9 pin: USART1 in transmission mode".

Then there is AN3155, which describes the actual USART protocol, which is initiated when the STM32 receives the byte 0x7F.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.