The Ware House


So far I have been flashing boards via UART or SWD interface using Windows applications. Now that I have validated the serial communication on Linux, I can use stm32flash to flash on both Linux and Windows.

Linux Build and Install

stm32flash project is hosted on SourceForge and the git repository is mirrored on gitlab.

I clone the repository from Sourceforge in my Projects folder.

$ cd ~/Projects
$ git clone stm32flash-code
Cloning into 'stm32flash-code'...
remote: Enumerating objects: 1357, done.
remote: Counting objects: 100% (1357/1357), done.
remote: Compressing objects: 100% (682/682), done.
remote: Total 1357 (delta 912), reused 996 (delta 671)
Receiving objects: 100% (1357/1357), 1.04 MiB | 74.00 KiB/s, done.
Resolving deltas: 100% (912/912), done.

Build on Linux doesn’t show any warnings.

$ cd stm32flash-code
$ make
cc -Wall -g   -c -o dev_table.o dev_table.c
cc -Wall -g   -c -o i2c.o i2c.c
cc -Wall -g   -c -o init.o init.c
cc -Wall -g   -c -o main.o main.c
cc -Wall -g   -c -o port.o port.c
cc -Wall -g   -c -o serial_common.o serial_common.c
cc -Wall -g   -c -o serial_platform.o serial_platform.c
cc -Wall -g   -c -o stm32.o stm32.c
cc -Wall -g   -c -o utils.o utils.c
cd parsers && make parsers.a
make[1]: Entering directory '~/Projects/stm32flash-code/parsers'
cc -Wall -g   -c -o binary.o binary.c
cc -Wall -g   -c -o hex.o hex.c
ar rc parsers.a binary.o hex.o
make[1]: Leaving directory '~/Projects/stm32flash-code/parsers'
cc  -o stm32flash dev_table.o i2c.o init.o main.o port.o serial_common.o serial_platform.o stm32.o utils.o parsers/parsers.a

I test the newly compiled command by calling it without argument “./stm32flah” and with the serial port where the USB to UART adapter is plugged in.

“./stm32flash” gives a detailed help of the command.

Calling it with the serial port argument where the board is plugged in and set in bootloader mode gives a description of the chipset detected.

$ ./stm32flash /dev/ttyUSB0
stm32flash 0.5

Interface serial_posix: 57600 8E1
Version      : 0x31
Option 1     : 0x00
Option 2     : 0x00
Device ID    : 0x0444 (STM32F03xx4/6)
- RAM        : Up to 4KiB  (2048b reserved by bootloader)
- Flash      : Up to 32KiB (size first sector: 4x1024)
- Option RAM : 16b
- System RAM : 3KiB

I install the command by moving the executable to my local bin directory.

$ mv stm32flash ~/bin

If everything goes well, I will later strip and compress (with upx) the executable.

Regression Testing

As my board has been already flashed on Windows, I can perform a simple regression test.

  • Read the content of the chipset memory as flashed with the Windows application.
  • Flash the same executable using Linux version of stm32flash.
  • Read back the newly programmed chipset memory.
  • Compare the two read out.

Reading 1 KB with stm32flash.

$ stm32flash -r read.bin -S 0x08000000:1024 /dev/ttyUSB0

Writing the executable in hex format.

$ stm32flash -w f030f4.hex /dev/ttyUSB0

I didn’t expect to find any differences but when I compare the readout using od, there is a 3 bytes difference at offset 0x19D.

STMicroelectronics Flash Loader Windows Application wrote three extra bytes 0xFF, 0x1E and 0x43.

000190 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 ff 1e 43

stm32flash left those 3 bytes in their erased state 0xFF.

000190 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 ff ff ff

The length of the executable written in flash is 413 or 0x19D. This is the same length as the .text section.

$ make
   text    data     bss     dec     hex filename
    413       0       4     417     1a1 f030f4.elf

As there is no initialized data, word alignment has not been performed by the linker and STMicroelectronics Flash Loader seems to write words, not bytes and has an issue with clearing the partially initialized last word to be written.

This does not affect execution as those three extra bytes are not referenced by the code, but could pop up again at a later time when it would be more difficult to diagnosticate.

It’s possible to fix STMicroelectronics Flash Loader as the source is available for Visual C++.

But I am more concerned about the way the linker script handles the section alignment. It generates padding between .text and the copy of the initialized data instead of making sure .text always ends on a word boundary.

So I add an ALIGN(4) directive in the linker script at the end of the .text section to secure that .text size will always be a multiple of words.

    .text :
        . = ALIGN(4);
    } > FLASH

Now if I build a new executable, the .text section is padded to a word boundary.

$ make
   text    data     bss     dec     hex filename
    416       0       4     420     1a4 f030f4.elf

If I flash now the board using either stm32flash or the STMicroelectronics Flash Loader Windows application I get the same flash memory content.

000190 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 00 00 00

Build and Install on Windows

There is a Windows binary that can be downloaded from stm32flash project page on SourceForge. But I did clone and build using both Cygwin and MSYS2 64bit environments on Windows.

The build phase gave more warnings than the Linux version, this is mostly due to stricter warnings in the GCC compiler version.

Usage of stm32flash only differs in the name of the serial device, in my case COM4 instead of /dev/ttyUSB0.


This step was mainly to make sure I develop with the same tools both on Linux and Windows. I spotted a minor issue with the serial flash loader I was using so far on Windows and I made sure this would not cause problems later by improving the linker script.

Next I will write an application which make better use of transmission than hello.

Back to top