Flashing via USART
Most STM32 devices have an on-board (first-level) boot-loader (see Table1 of AN2606 for an overview of supported devices). The boot-loader allows developers to flash MCU’s internal ROM memory via SPI, CAN, USB, I2C etc. but for our project we want to connect via USART to the STM32 MCU.
The USART protocol that is used to communicate between PC-tool and stm32 boot-loader is described in application note AN3155. But before communication is possible you need to activate the boot-loader.
The boot-loader starts listening on USART1 when the boot pins BOOT0 and BOOT1 are configured as ‘System memory’. This means:
- BOOT0: logical 1,
- BOOT1: logical 0.
A full description of the different pin configurations can be found in AN2606.
On the STM32VLDISCOVERY board BOOT1 (bridge SB2) is connected to GROUND via a pull-down. But BOOT0 needs a pull-up. This blog post clearly describes how to achieve this. In short, connect pin 5V to pin Boot by using a 270Ohm pull-up resistor. Then, BOOT0 becomes a logical 1 and boot mode is enabled (after a reset!).
Here is a picture (I am using 2 resistors in series here):
STM32 Boot-loader usage
Several PC-side tools exist to communicate with the stm32 boot-loader. Here is a non-exhaustive list:
- stm32flash: C-based
- stm32 usart boot-loader (bootstm32): java-based
- stm32sprog: C-based
- stm32loader: python-based
We have only tested stm32flash, a C-based implementation… of course . This tool has windows support as well.
Using stm32flash is pretty straightforward, but here are some tips and tricks.
The basic command to get device info is: stm32flash /dev/ttyUSB0. This command prints some ST device info for you such as RAM size, Flash size etc. If you get a permission denied then you can probably solve this by following these steps:
- ls -l /dev/ttyUSB0 -> so you can see the group of the device
- add your user to this group (e.g. by editing /etc/group or doing a usermod -a -G dialout username)
- to load your new groups: re-login, run exec su -l username or use newgrp.
Of course, you can always add sudo in front of the command line but in this case you execute as superuser.
Next thing to do is disable flash write-protection: stm32flash -u /dev/ttyUSB0.
And then you can write the flash: stm32flash -w main.hex -v -g 0×08000000 /dev/ttyUSB0 (by default, baud is 57600). An explicit erase is not necessary. In this example, a hex file is flashed, but a bin(ary) format is possible as well. 0×08000000 is the base address of the flash on the STM32F100 MCU. After this command the application is started. It is possible to explicitly start the application from the boot-loader with stm32flash -g 0 /dev/ttyUSB0.