USB CDC Bootloader for STM32F103C8

When designing a device on a microcontroller, the question arises about updating the device firmware. Moreover, the process of updating the firmware itself should be simple and accessible for an ordinary user. And specifically for the STM32F103C8 microcontroller, it is possible to download the firmware via UART. That is, it is necessary to add a USB-UART converter microcircuit to the circuit. Or use the hardware capabilities of the USB microcontroller, which I did. I was interested in the question of the possibility of updating the firmware via USB. Some MCUs even have a hardware USB bootloader, but not on the STM32F103C8, so I had to implement everything in software. On the software side for STM32, there is a USB Library from STMicroelectronics with implemented USB classes and examples. In particular, I was interested in the DFU class i.e. download firmware via USB. This class has already implemented its own set of commands for interaction between the MC and the application on the PC “STM32CubeProgrammer”. But I wanted something of my own, custom and unlimited by this set of commands. And the thought came “Why not implement all this in the CDC class?” Here, the size of the bootloader turned out to be about the same, but the main thing is you can implement your own set of commands, work on a PC with a serial port and, accordingly, it is clearer how to write an application for a PC. I have little experience in writing applications using the QT library in C ++, so a program for the USB bootloader was created with its help.

Consider the operation and configuration of the bootloader itself on the MK. The project was created in STM32CubeIDE, the size of the bootloader turned out to be 15 KB. In the main.c file there is a condition under which the MC works in bootloader mode, or control is transferred to the user application:


We can optionally set any condition for entering the bootloader mode, in my case you need to close the B0 leg to the ground when loading the MC. And then the MK will go into bootloader mode and when connected via USB on the PC side it will be defined as a virtual COM port. Otherwise, the main firmware will be executed. The memory.h file contains the addresses of the beginning of the main firmware and the end of the program memory:

#define APPLICATION_ADDRESS    0x08003C00
#define FLASH_END              0x0801FFFF

Now let’s prepare the custom firmware for loading. Let’s take a simple LED blinking as an example. In the project for CubeIDE in the STM32F103C8TX_FLASH.ld file, you need to change the address of the start of the program execution to 0x8003C00:

/* Memories definition */
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 20K
  FLASH    (rx)    : ORIGIN = 0x8003C00,   LENGTH = 64K

In the system_stm32f1xx.c file, set the offset of the vector table 0x3C00:

/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x3C00 /*!< Vector Table base offset field.
                                  This value must be a multiple of 0x200. 

Now you can proceed to download this firmware. We put a jumper on the B0 leg and connect the board via USB. Launch the “USB CDC Programmer” application:

To search for available COM ports, click “Refresh”, select the appeared port in the list and click “Connect”. It will display a message about successful connection of the board and the name of the connection button will change to “Disconnect”:

If before that another firmware was loaded into the board, then it must be deleted by clicking on “Erase”. In this case, the entire memory area is erased, starting from address 0x8003C00 and up to the end of the program memory. Next, click “Open” and in the dialog box select the firmware file in the .bin format (For now, only this file format is supported). The table shows the firmware data, the name and size of the file in the logs. Click “Download” and after a while the firmware will be loaded:

Now you can turn off the board, remove the jumper and make sure the firmware is working. If necessary, it is possible to read the firmware and save it to a file on the computer. The MK memory is read starting from the address 0x8003C00 and up to the first number 0xFFFFFFFF.

I attach to the article:

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *