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

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.


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


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.