One of the more attractive features or the STM32 processors, at least in their more recent revisions, is the presence of a built-in serial bootloader. JTAG is all very well but you need extra hardware and then software to drive it. If you want to do in-circuit debugging, it is ideal. However, for my use, I don’t much want a 20 pin header and I find the debugging feature for a micromouse to be a little redundant. Debugging can be done on a static test rig. But then, if I want to update the mouse software, a serial bootloader is perfect and I can use the same serial connection to communicate with my code when it is running
The STM32 has two pins which can be used to determine where the processor looks for code when it starts up. These are BOOT0 and BOOT1. The following table gives their function: [Corrected 16 May 2009 – PH]
|X||0||Boot from user flash|
|0||1||Boot from System Memory|
|1||1||Boot from embedded RAM|
If we forego the option to boot from RAM, we can hold BOOT1 low and add a switch or jumper to BOOT0. If BOOT0 is high after a reset, the processor boots from system memory which, as delivered, means the bootloader. Holding the pin low boots from the on-board user flash and executes our code.
You can find a full description of the bootloader in the ST document AN2606
ST provide a flash loader application both as a Windows GUI application and as a command line program. Both versions are really just too much like hard work and you won’t use them much before looking for a better way. And there is one. It is a Python script originally written by Ivan A-R and available from here:
The page is in Russian but the comments and help are in English. The version there seems to have a small bug relating to writing a file containing the contents of the chip. I found a fix for that but can’t remember the location of that page so here is a revised version that I have used to successfully write and read the STM32F103RBT6 devices on my test boards.
My development platform at present is a Mac. That means I get Python already present on the system. If you have a Linux box, it may well have Python installed or it will be easy to do so. It can also be readily installed on Windows. Be sure to get Python 2.6.x as there are syntax differences that will stop the script from running in Python 3. Have a look here:
Before you can use the script, you will also need to get the PySerial library from here:
This is needed so that Python can talk to the serial ports. Once you have the script, run it with the –h switch to get some help:
stm32loader.py [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [file.bin] -h This help -q Quiet -V Verbose -e Erase -w Write -v Verify -r Read -l length Length of read -p port Serial port (default: /dev/tty.usbserial-ftCYPMYJ) -b baud Baud speed (default: 115200) -a addr Target address ./stm32loader.py -e -w -v example/main.bin
My script defaults to the normal location of my serial port. You will need to change that to suit your circumstances or use the appropriate switches. Note that the loader only understands binary files, not hex files. If you are using another toolchain you will need to get it to create binary files. If you have a hex file, it can be converted to a binary file with the following command:
arm-eabi-objcopy -I ihex -O binary data.hex data.bin
It is also necessary to erase the chip on each write so your typical write command looks like this:
stm32loader -evw data.bin
The script will know how much data to transfer and will default to writing it to location 0x08000000. Reading data requires that you tell the script how much you want and the name of the file you want it stored in.
stm32loader –r –l 0x1000 data.bin
To use the loader
- set your switch/jumper to make BOOT0 high
- press the reset button on the board
- run the script
- wait until it is done
- set the switch/jumper to make BOOT0 low
- reset the board to run your code
Once in loader mode, the chip waits for data from the computer and does an autobaud detection to determine transfer speed. Sometimes I seem to need to do this a couple of times before it works. That may be because I would be better off with a lower speed. Next we need to write something worth putting in the chip. Stay tuned.