Mecrisp Forth for the STM32WB
Forth is an interactive and extensible language, built-in lexical analysis (tokenizer, parser), needs less than 20 KiB Flash and 4 KiB RAM.

A possible alternative is MicroPython, but it needs more than 250 (rather 350) KiB of Flash . What about uLisp? It is also small (32 KiB) and self-contained, but it needs garbage collection, that takes about 2 ms @ 40 MHz (real-time programming and garbage collection is not a dream team).

See MecrispCube for a Mecrisp-Stellaris Forth embedded in the STM32 Cube ecosystem.



Linux packages:
  • cross-arm-binutils
  • cross-arm-none-gcc9
  • cross-arm-none-newlib-devel
  • openocd for debugging



It is tedious job to find all the registers in the data sheets. There is CubeMX to create code for STM's MCUs, but mecrisp use pure assembler. There is convenient way to create equates for the assembler.

SVD 2 Forth

Install the STM32CubeIDE and get the STM32WBxx_CM4.svd from the folder:

Version 1.6: stm32cubeide_1.1.0/plugins/
Version 1.7: stm32cubeide_1.2.0/plugins/

Install the Mecrisp-Stellaris and copy the STM32WBxx_CM4.svd into common/svd2forth-v3. Edit the Makefile

common/svd2forth-v3> diff Makefile Makefile~
< FOLDED_SVD            = STM32WBxx_CM4.svd
> FOLDED_SVD            = STM32L07x.svd

Edit the shell script Replace gsed with sed.

Generate the Forth and Assembler source files:

common/svd2forth-v3> make everything
common/svd2forth-v3> make mem

You can get STM32WBxx_CM4.svd.equates.s from my site: STM32WBxx_CM4.svd.equates.s

Create the Binary for STM32WB


There is good architecture diagram from STM32MPU Wiki (consider only the Cortex-M4 parts):



OpenOCD 0.10.0 does not support STM32WB, therefore I built the OpenOCD from the sources.

$ git clone openocd-code

But openSUSE' jimtcl Package conflicts with the configure script, to prevent this:

$ mv /usr/bin/jimsh /usr/bin/jimsh-unused

The usual configure/make/install:

$ ./configure
$ make
# make install

The stm32wbx.cfg is derived from st_nucleo_l4.cfg.

$ openocd -f /usr/local/share/openocd/scripts/board/st_nucleo_wb.cfg
Open On-Chip Debugger 0.10.0+dev-01031-gff6d0704 (2020-01-19-11:35)
Licensed under GNU GPL v2
For bug reports, read
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 500 kHz
Info : STLINK V2J34M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.221593
Info : stm32wbx.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections

Test the server from another terminal:

$ telnet localhost 4444
Trying ::1...
telnet: connect to address ::1: Connection refused
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> shutdown
shutdown command invoked
Connection closed by foreign host.

Sample debugging session:

$ gdb
GNU gdb (GDB; openSUSE Tumbleweed) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
(gdb) file mecrisp-stellaris-stm32wb55.elf
Reading symbols from mecrisp-stellaris-stm32wb55.elf...
(gdb) break Reset
Breakpoint 1 at 0x8003aaa: file mecrisp-stellaris-stm32wb55.s, line 89.
(gdb) break faulthandler
Breakpoint 2 at 0x80038ea: file ../common/interrupts-common.s, line 144.
(gdb) break uart_init
Breakpoint 3 at 0x800146e: file terminal.s, line 31.
(gdb) target remote localhost:3333
Remote debugging using localhost:3333
0x1fff5904 in ?? ()
(gdb) monitor reset
Unable to match requested speed 500 kHz, using 480 kHz
Unable to match requested speed 500 kHz, using 480 kHz
(gdb) load
Loading section .text, size 0x3c18 lma 0x8000000
Start address 0x8000000, load size 15384
Transfer rate: 19 KB/sec, 15384 bytes/write.
(gdb) continue
Note: automatically using hardware breakpoints for read-only addresses.

Flash mecrisp to the Target

Nucleo Board

Connect Nucleo's ST-LINK USB to you PC. Erase the flash e.g. by openOCD, we use 768 KiB Right 192 sectors.

$ telnet localhost 4444
Trying ::1...
telnet: connect to address ::1: Connection refused
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> reset init
Unable to match requested speed 500 kHz, using 480 kHz
Unable to match requested speed 500 kHz, using 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08003aae msp: 0x20000430
> flash erase_sector 0 0 192
erased sectors 0 through 192 on flash bank 0 in 4.583453s
> flash write_image mecrisp-stellaris-stm32wb55.hex
device idcode = 0x20016495 (STM32WB5x - Rev: 2.1)
flash size = 1024kbytes
flash mode : single-bank
Padding 4 bytes to keep 8-byte write size
block write succeeded
wrote 15404 bytes from file mecrisp-stellaris-stm32wb55.hex in 0.329747s (45.620 KiB/s)

> shutdown
shutdown command invoked
Connection closed by foreign host.

USB Dongle

The USB Dongle does not have a ST-Link interface, but the STM32WB has a built-in boot-loader. This bootloader works over USB. As programmer I use the CLI from the STM32CubeProg package.

$ alias cubepgmcli='/opt/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI'
$ cubepgmcli -c port=USB1 -ob displ

BTW you can flash the Nucleo Board in the same way.

Update BLE Stack

You can find the BLE Stack and FUS in STM32CubeWB, in the directory Projects/STM32WB_Copro_Wireless_Binaries.

Using USB_USER and the built-in bootloader (activate with jumper between CN7.5 and CN7.7)

$ alias cubepgmcli='/opt/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI'
STM32Cube_FW_WB_V1.4.1/Projects/STM32WB_Copro_Wireless_Binaries> cubepgmcli -c port=USB1 -fwdelete
STM32Cube_FW_WB_V1.4.1/Projects/STM32WB_Copro_Wireless_Binaries> cubepgmcli -c port=USB1 -fwupgrade stm32wb5x_FUS_fw.bin 0x080EC000 firstinstall=0
STM32Cube_FW_WB_V1.4.1/Projects/STM32WB_Copro_Wireless_Binaries> cubepgmcli -c port=USB1 -fwupgrade stm32wb5x_BLE_Stack_full_fw.bin 0x080CE000 firstinstall=1

Using ST-LINK (here to show the option bytes, SBRV : 0x33800 means start address 4 * SBRV + 0x08000000 = 0x080CB000, 3D000 means there is no stack):

psi@homer:~/Dropbox/wbForth/CubeWB> cubepgmcli -c port=SWD -ob displ
                       STM32CubeProgrammer v2.10.0

Log output file:   ob.log
ST-LINK SN  : 0030003E3137510539383538
Board       : STLINK-V3SET
Voltage     : 3.27V
SWD freq    : 24000 KHz
Connect mode: Under Reset
Reset mode  : Hardware reset
Device ID   : 0x495
Revision ID : Rev Y
Device name : STM32WB5x
Flash size  : 1 MBytes
Device type : MCU
Device CPU  : Cortex-M4
BL Version  : 0xd5
Debug in Low Power mode enabled


  Bank          : 0x00
  Address       : 0x58004020
  Size          : 96 Bytes

  Bank          : 0x01
  Address       : 0x58004080
  Size          : 8 Bytes


   Read Out Protection:

     RDP          : 0xAA (Level 0, no protection)

   BOR Level:

     BOR_LEV      : 0x4 (BOR Level 4 reset level threshold is around 2.8 V)

   User Configuration:

     nBOOT0       : 0x1 (nBOOT0=1 Boot from main Flash)
     nBOOT1       : 0x1 (Boot from code area if BOOT0=0 otherwise system Flash)
     nSWBOOT0     : 0x0 (BOOT0 taken from the option bit nBOOT0)
     SRAM2RST     : 0x0 (SRAM2 erased when a system reset occurs)
     SRAM2PE      : 0x1 (SRAM2 parity check disable)
     nRST_STOP    : 0x1 (No reset generated when entering the Stop mode)
     nRST_STDBY   : 0x1 (No reset generated when entering the Standby mode)
     nRSTSHDW     : 0x1 (No reset generated when entering the Shutdown mode)
     WWDGSW       : 0x1 (Software window watchdog)
     IWGDSTDBY    : 0x1 (Independent watchdog counter running in Standby mode)
     IWDGSTOP     : 0x1 (Independent watchdog counter running in Stop mode)
     IWDGSW       : 0x1 (Software independent watchdog)
     IPCCDBA      : 0x0  (0x0)

   Security Configuration Option bytes - 1:

     ESE          : 0x1 (Security enabled)

   PCROP Protection:

     PCROP1A_STRT : 0x1FF  (0x80FF800)
     PCROP1A_END  : 0x0  (0x8000800)
     PCROP_RDP    : 0x0 (PCROP zone is kept when RDP is decreased)
     PCROP1B_STRT : 0x1FF  (0x80FF800)
     PCROP1B_END  : 0x0  (0x8000800)

   Write Protection:

     WRP1A_STRT   : 0xFF  (0x80FF000)
     WRP1A_END    : 0x0  (0x8000000)
     WRP1B_STRT   : 0xFF  (0x80FF000)
     WRP1B_END    : 0x0  (0x8000000)

   Security Configuration Option bytes - 2:

     SFSA         : 0xC7  (0x80C7000)
     FSD          : 0x0 (System and Flash secure)
     DDS          : 0x1 (CPU2 debug access disabled)
     C2OPT        : 0x1 (SBRV will address Flash)
     NBRSD        : 0x0 (SRAM2b is secure)
     SNBRSA       : 0xF  (0x2003BC00)
     BRSD         : 0x0 (SRAM2a is secure)
     SBRSA        : 0xA  (0x20032800)
     SBRV         : 0x31C00  (0x20000000)

-- Peter Schmid - 2019-12-29


Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formatfs 1b.fs r1 manage 0.7 K 2020-01-12 - 10:21 PeterSchmid  
PNGpng 700px-GDB_openOCD_focus_graph.png r1 manage 103.5 K 2020-01-19 - 16:11 PeterSchmid  
Unknown file formatext Makefile r1 manage 0.8 K 2020-01-24 - 21:14 PeterSchmid  
Unknown file formatsvd STM32WBxx_CM4.svd r1 manage 1536.1 K 2019-12-31 - 18:11 PeterSchmid  
Unknown file formats STM32WBxx_CM4.svd.equates.s r1 manage 447.3 K 2020-01-12 - 10:21 PeterSchmid  
Unknown file formatfs bitfields.fs r1 manage 526.9 K 2020-01-12 - 10:21 PeterSchmid  
Unknown file formats flash.s r2 r1 manage 6.7 K 2020-01-26 - 22:16 PeterSchmid  
Unknown file formats interrupts.s r1 manage 1.5 K 2020-01-26 - 22:16 PeterSchmid  
Unknown file formatbin mecrisp-stellaris-stm32wb55.bin r2 r1 manage 15.0 K 2020-01-27 - 22:23 PeterSchmid  
Unknown file formathex mecrisp-stellaris-stm32wb55.hex r2 r1 manage 42.4 K 2020-01-27 - 22:23 PeterSchmid  
Unknown file formats mecrisp-stellaris-stm32wb55.s r1 manage 3.9 K 2020-01-26 - 22:16 PeterSchmid  
Unknown file formatext memmap r1 manage 0.2 K 2020-01-26 - 22:16 PeterSchmid  
Unknown file formatfs memmap.fs r1 manage 132.7 K 2020-01-12 - 10:21 PeterSchmid  
Unknown file formatfs nucleo-bsp.fs r1 manage 1.2 K 2020-01-28 - 13:59 PeterSchmid  
JPEGjpg nucleo-header.jpg r1 manage 84.7 K 2020-01-26 - 09:59 PeterSchmid  
Unknown file formatcfg st_nucleo_wb.cfg r1 manage 0.3 K 2020-01-19 - 15:32 PeterSchmid  
JPEGjpg stm32wb-nucleo.jpg r1 manage 85.8 K 2019-12-30 - 16:51 PeterSchmid  
Unknown file formats terminal.s r1 manage 4.6 K 2020-01-26 - 22:16 PeterSchmid  
Unknown file formats turbo.s r1 manage 2.2 K 2020-01-24 - 21:14 PeterSchmid  
Unknown file formats vectors.s r1 manage 4.5 K 2020-01-26 - 22:16 PeterSchmid  
Edit | Attach | Watch | Print version | History: r34 < r33 < r32 < r31 < r30 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r34 - 2022-10-18 - PeterSchmid
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2023 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback