> What’s New ? <

Flashing Mecrisp-Stellaris onto a STM32: Methods

There are a number of methods to upload a binary image of Mecrisp-Stellaris to a STM32 MCU. These include SWD, JTAG and Serial Bootloader.

If this is your first time, and youre in a hurry, checkout the Quickstart page ?

Flashing Methods

Difficulty Score, 1 is easiest.

Difficulty

Flashing Method

Software

Required Hardware

URL

1

Serial Bootloader

stm32loader.py

3.3v USB Serial Dongle

stm32loader.py

1

St-flash (FreeBSD)

st-flash (FreeBSD)

SWD

Freebsd, OpenBSD use the port or package “ devel/stlink “

1

df-util

df-util

USB

http://dfu-util.sourceforge.net/

2

SWD

OpenOCD

JTAG or SWD

https://sourceforge.net/projects/openocd/

3

GDB

GDB over OpenOCD

JTAG or SWD

https://www.gnu.org/s/gdb/

Warning

stm32loader.py does not seem to erase at all. The ‘-e Erase’ option seems to have no effect with stm32f103, stm32L053 etc. This is a fatal problem when flashing a new version of Mecrosp-Stellaris to your MCU. Use SWD, df-util or JTAG instead. See this url for more information: https://community.st.com/s/question/0D50X00009Xkex4/unable-to-erase-flash-stm32l05-using-bootloader-via-spi-cmds

Note

use STM32FLASH instead, it is a Debian package: stm32flash -j /dev/ttyUSB0 ; stm32flash -k /dev/ttyUSB0 ; stm32flash -e 0 -w /path/to/mecrisp.bin /dev/ttyUSB0

Serial Bootloader

Note

See www.st.com/resource/en/application_note/cd00167594.pdf for which serial ports support bootloading on your STM32F MCU.

Your board will need one or two Boot Option Jumpers. On some Discovery boards only BOOT0 may be present as BOOT1 is internally tied to logic high inside the MCU and not available externally.

Howto flash Mecrisp-Stellaris using the Bootloader

  1. Download the latest Mecrisp-Stellaris tarball: http://mecrisp.sourceforge.net/

  2. Extract the binary for your MCU, in this case it’s mecrisp-stellaris-stm32fxxx.bin

  3. Hook up your 3.3v USB Serial Dongle to the USART 1 (only USART-1 supports the serial bootloader on a STM32F103xx (PA9-TX, PA10-RX) pins on your cheap Chinese target board . You can usually power the board from the dongle.

  4. Set the boot pin jumpers. Boot 0 to HIGH or 1. BOOT 1 will stay LOW or 0.

  5. Run something like this command “ python ./stm32loader.py -p /dev/cuaU0 -evw ./mecrisp-stellaris-stm32fxxx.bin “

  6. Set both boot pins to LOW, reset the power to the target

  7. Fire up your serial terminal and talk Forth to your MCU/Board.

Special note to use the Bootloader on a Discovery Board

Fast and simple, requires the use of Boot Option Jumpers, stm32loader.py and a serial 3.3v/USB dongle. Note the STM32F0 Discovery Board has a BOOT0 pin next to a VDD pin. A - E below describe how to use the inbuilt STM32F0 Serial Bootloader on a STM32F0 Discovery board, but many other Discovery boards have the same Bootloader Jumper Methods.

  1. Have a serial connection to PA9/10 (This is the default Mecrisp-Forth serial connection)

  2. Fit 0.1” pitch Option Jumper on the STM32F0 Discovery Board between ‘BOOT0’ and ‘VDD’. Borrow one from the nearby ST-LINK jumper pins.

  3. Press the STM32F0 Discovery Board RESET button

  4. Run the following CLI command “python ./stm32loader.py -p /dev/cuaU0 -evw ./mecrisp-stellaris-stm32f051.bin”

  5. Remove the Option Jumper from ‘BOOT0’ and ‘VDD’ and replace it on the ST-LINK header. DONE! Faster than SWD and easy, no need to find a usb cable etc.

A Unix friendly Bootloader: stm32loader.py

# python ./stm32loader.py -h
Usage: ./stm32loader.py [-hqVewvrX] [-l length] [-p port] [-b baud] [-a addr] [file.bin]
   -h          This help
   -q          Quiet
   -V          Verbose
   -e          Erase
   -w          Write
   -v          Verify
   -X          Reset after
   -r          Read
   -l length   Length of read
   -p port     Serial port (default: first USB-like port in /dev)
   -b baud     Baud speed (default: 115200)
   -a addr     Target address
   -s n        Skip writing N bytes from beginning of the binary (does not affect start address)
   -k          Change PCLK frequency to make USB stable on Espruino 1v43 bootloaders

   ./stm32loader.py -e -w -v example/main.bin
stm32loader.py -p /dev/cuaU16 -evw mecrisp-stellaris-stm32f103.bin
Reading data from mecrisp-stellaris-stm32f103.bin
Bootloader version 0x22
Chip id 0x410, STM32F1, performance, medium-density
Writing 20352 bytes to start address 0x8000000
Write 256 bytes at 0x8000000
Write 256 bytes at 0x8000100
Write 256 bytes at 0x8000200
...
Read 256 bytes at 0x8004F00
Verification OK
Mecrisp-Stellaris RA 2.3.9 for STM32F103 by Matthias Koch
 ok.
 ok.
 ok.

Details:

  • The serial bootloader is stored in the internal boot ROM memory (system memory) of STM32 devices. It is programmed by ST during production and cant be wiped or overwritten. Its main task is to download the application program to the internal Flash memory through one of the available serial peripherals (USART, CAN, USB, I2C, SPI, etc.). A communication protocol is defined for each serial interface, with a compatible command set and sequences.

  • Selection is using the two “boot” jumpers on the MCU board. Set Boot 1 = LOW (0) and Boot 2 = HIGH (1) before using the bootloader. After bootloading set them both to LOW (0) to run the binary you just uploaded and power cycle the board.

  • A ‘bootloader’ program needs to be run on the PC, I’ve used stm32loader.py without any problems on a Shenzhen LC mini STM32FC8T6 board from China.

  • Which USART do I use on a chip/board with multiple USARTS ? See STM Application note cd00167594 for your MCU. Mecrisp-Stellaris usually uses USART-1

  • See this table for serial port pins and connections to find your most likely Bootloader port connections.

  • After Mecrisp-Stellaris has uploaded, set the two boot jumpers to LOW and reset the power. You should then be able to use a serial terminal to talk Forth to the board using exactly the same serial port on the target board.

  • Mecrisp-Stellaris takes 6 seconds to upload its 23KB image with stm32loader.py and seems to work everytime on a cheap $9 Shenzhen LC mini STM32FC8T6 board from China.

Warning

Requires a USB/3.3v cable or dongle. You can’t use RS232, if you do you may blow up your STM32 chip.

Boot Pin Functions

Pins BOOT0 and BOOT1 select how the STM32 starts

BOOT 1

BOOT 0

Boot mode

X

0

User Flash memory (application)

0

1

System memory (bootloader)

1

1

Embedded SRAM

Saving a on chip binary

Saving 645kB of flash to “saved-binary.bin”

./stm32loader.py -r -a  0x08000000 -l 0x10000 -p /dev/ttyUSB0 saved-binary.bin

DF-UTIL

Df-util is a host side implementation of the DFU 1.0 and DFU 1.1 specifications of the USB forum. DFU is intended to download and upload firmware to/from devices connected over USB. It ranges from small devices like micro-controller boards to mobile phones. Using dfu-util you can download firmware to your DFU-enabled device or upload firmware from it.

Example usage

Flashing a .dfu (special DfuSe format) file to the device

$ dfu-util -a 0 -D /path/to/dfuse-image.dfu

Reading out 1 KB of flash starting at address 0x8000000

$ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin

Flashing a binary file to address 0x8004000 of device memory and ask the device to leave DFU mode

$ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin

Unhandled Interrupt 00000003

Warning

I have observed that failure to fully erase the Flash memory prior to flashing Mecrisp-Stellaris often results in endless “Unhandled Interrupt 00000003” messages, this can happen with df-util because the erase-flash command is undocumented for fear of people bricking their devices.

How To Erase Using Df-util

https://forum.mystorm.uk/t/how-to-clear-all-flash/373 (erikolson)

Here’s how I flash with erase:

dfu-util -a 0 -d 0483:df11 -s 0x8000000:mass-erase:force -D mecrisp-stellaris-stm32l433.bin -t 1024

You can “upload” the flash to your desktop to see if you do have unwanted flash content:

#!/bin/bash
# verify upload
rm current.bin
dfu-util -a 0 -d 0483:df11 -s 0x8000000 -U current.bin
od -x mecrisp-stellaris-stm32l433.bin > in.txt
od -x current.bin > out.txt
sdiff -w 216 -s in.txt out.txt | more

This is also useful if you suspect corruption which happens if the upload is not a 4-byte multiple.

SWD

  • Uses the SWD pins on the MCU and STLINKv2 firmware (factory installed on STM32 “Discovery Boards”)

  • Requires a USB/SWD programmer (Every STM32 “Discovery Board” is a USB to SWD programmer and comes with “STLINK”)

  • Requires a USB port on the PC

  • Use STLINKv2 only, avoid all old STLINKv1 SWD boards like the plague

  • Can be used for On Chip Debugging with GDB

Howto flash Mecrisp-Stellaris using SWD

To be written ..

JTAG

  • Older less used method

  • Uses the JTAG pins on the MCU

  • Requires a USB/JTAG Dongle and a JTAG connector on the MCU pcb.

  • Requires a USB port on the PC

  • The author uses a ‘Olimex ARM-USB-TINY-H” USB to 20 pin IDC JTAG connector on both Linux and FreeBSD

  • Can be used for On Chip Debugging with GDB

Howto flash Mecrisp-Stellaris using JTAG

  • Board: STM (Shenzen Mini-Arm board) STM32F103C8T6

  • FreeBSD OS is used in this example, so your file locations, names and versions may differ to mine if you use Linux etc.

  • Olimex ARM-USB-TINY-H JTAG dongle

  • OpenOCD is used to Flash the STM32F103C8T6

  • Usb to 3.3v dongle for talking serial to Forth on the mini-stm32f103 board via a serial terminal. PL2303 chipsets are recommended being Unix friendly.

  • Picocom is used in this example as the serial terminal

The Hardware used

_images/mini-stm32F103C8T6-board-jtag-serial-1.jpg

Open a Root Xterm to run OpenOCD. Leave it running until MCU is flashed:

root@Gronk:/home/tp # openocd -f /usr/local/share/openocd/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f /usr/local/share/openocd/scripts/target/stm32f1x.cfg
Open On-Chip Debugger 0.9.0 (2016-02-03-08:48)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : clock speed 1000 kHz
Info : JTAG tap: stm32f1x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32f1x.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

Open a Telnet session to localhost 4444, which is how the user talks to OpenOCD

tp@Gronk:~/projects/programming-languages/forth/mecrisp-stellaris/mecrisp-stellaris-2.2.4/stm32f103-ra# telnet localhost 4444 
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger

> poll
background polling: on
TAP: stm32f1x.cpu (enabled)
target state: halted
target halted due to undefined, current mode: Thread 
xPSR: 00000000 pc: 00000000 msp: 00000000

> reset halt
JTAG tap: stm32f1x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
JTAG tap: stm32f1x.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00003b6a msp: 0x20000330

Check how much Flash you have

>  flash probe 0     
device id = 0x20036410
flash size = 64kbytes
flash 'stm32f1x' found at 0x08000000

>  flash probe 1
flash bank 1 does not exist
flash bank '#1' is out of bounds

> flash probe 2
flash bank 2 does not exist
flash bank '#2' is out of bounds

>

Check if the Flash is erased

> flash erase_check 0
device id = 0x20036410
flash size = 64kbytes
successfully checked erase state
        #  0: 0x00000000 (0x400 1kB) not erased
        #  1: 0x00000400 (0x400 1kB) not erased
        #  2: 0x00000800 (0x400 1kB) erased
        #  3: 0x00000c00 (0x400 1kB) erased
        #  4: 0x00001000 (0x400 1kB) not erased
	... all not erased
        # 56: 0x0000e000 (0x400 1kB) not erased
        # 57: 0x0000e400 (0x400 1kB) erased
        # 58: 0x0000e800 (0x400 1kB) erased
        # 59: 0x0000ec00 (0x400 1kB) erased
	# 60: 0x0000f000 (0x400 1kB) erased
        # 61: 0x0000f400 (0x400 1kB) erased
        # 62: 0x0000f800 (0x400 1kB) erased
        # 63: 0x0000fc00 (0x400 1kB) erased
>

Mass erase all the Flash

> stm32f1x mass_erase 0
stm32x mass erase complete

Check the Flash is really erased

> flash erase_check 0  
successfully checked erase state
        #  0: 0x00000000 (0x400 1kB) erased
	... all erased
        # 63: 0x0000fc00 (0x400 1kB) erased
>

Flash Mecrisp-Stellaris onto the STM32F103C8T6

> flash write_image /home/tp/projects/programming-languages/forth/mecrisp-stellaris/mecrisp-stellaris-2.2.4/stm32f103-ra/mecrisp-stellaris-stm32f103.bin 0x08000000
wrote 20336 bytes from file /home/tp/projects/programming-languages/forth/mecrisp-stellaris/mecrisp-stellaris-2.2.4/stm32f103-ra/mecrisp-stellaris-stm32f103.bin in 0.652892s (30.418 KiB/s)
>

Check the Flash, how much space did Mecrisp-Stellaris use up ?

flash erase_check 0
successfully checked erase state
        #  0: 0x00000000 (0x400 1kB) not erased
        #  1: 0x00000400 (0x400 1kB) not erased
        #  2: 0x00000800 (0x400 1kB) not erased
        #  3: 0x00000c00 (0x400 1kB) not erased
        #  4: 0x00001000 (0x400 1kB) not erased
        #  5: 0x00001400 (0x400 1kB) not erased
        #  6: 0x00001800 (0x400 1kB) not erased
        #  7: 0x00001c00 (0x400 1kB) not erased
        #  8: 0x00002000 (0x400 1kB) not erased
        #  9: 0x00002400 (0x400 1kB) not erased
        # 10: 0x00002800 (0x400 1kB) not erased
        # 11: 0x00002c00 (0x400 1kB) not erased
        # 12: 0x00003000 (0x400 1kB) not erased
        # 13: 0x00003400 (0x400 1kB) not erased
        # 14: 0x00003800 (0x400 1kB) not erased
        # 15: 0x00003c00 (0x400 1kB) not erased
        # 16: 0x00004000 (0x400 1kB) not erased
        # 17: 0x00004400 (0x400 1kB) not erased
        # 18: 0x00004800 (0x400 1kB) not erased
        # 19: 0x00004c00 (0x400 1kB) not erased
        # 20: 0x00005000 (0x400 1kB) erased
	... all erased
        # 63: 0x0000fc00 (0x400 1kB) erased
>
If you want to Flash by calling OpenOCD from a script, instead of a open OpenOCD terminal and manual Telnet session, you can use this command instead.
  • This command flashes, verifies and exits, but does not erase any pre existing Forth Dictionary.

root@Gronk:/home/tp/projects/programming-languages/forth/mecrisp-stellaris/mecrisp-stellaris-2.2.4/stm32f103-ra # openocd -f /usr/local/share/openocd/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f /usr/local/share/openocd/scriptsget/stm32f1x.cfg -c "program mecrisp-stellaris-stm32f103.bin verify exit 0x08000000"

Open On-Chip Debugger 0.9.0 (2016-02-03-08:48)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : clock speed 1000 kHz
Info : JTAG tap: stm32f1x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32f1x.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: stm32f1x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32f1x.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00004d92 msp: 0x2000038c
** Programming Started **
auto erase enabled
Info : device id = 0x20036410
Info : flash size = 64kbytes
wrote 20480 bytes from file mecrisp-stellaris-stm32f103.bin in 1.155165s (17.314 KiB/s)
** Programming Finished **
** Verify Started **
verified 20336 bytes in 0.311900s (63.672 KiB/s)
** Verified OK **
shutdown command invoked
Connect a terminal to the board and start talking in Forth.
  • The mini-stm32f103 board uses pins PA9 (TX) and PA10 (RX), and these will need to be wired to your usb to 3.3v cable or dongle.

  • OpenOCD terminals may need to be exited or the board reset switch pressed

tp@Gronk:~/projects/programming-languages/forth/mecrisp-stellaris/mecrisp-stellaris-2.2.4/stm32f103-ra# picocom -b 115200 /dev/cuaU5 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l100"

picocom v2.1

port is        : /dev/cuaU5
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : ascii-xfr -s -l100
receive_cmd is : rz -vv -E
imap is        : crcrlf,lfcrlf,
omap is        : crlf,delbs,
emap is        : crcrlf,delbs,

Type [C-a] [C-h] to see available commands

Terminal ready
Mecrisp-Stellaris RA 2.2.4 for STM32F103 by Matthias Koch
  ok.
  ok.

See also

PROBLEMS ? See This Page