This post is also available in: cs

Development tools are probably the biggest weakness of the whole STM8 ecosystem. The manufacturer provides the STVD development environment (guide here), which is adequate, but old and no longer developed. Sometimes it happens that on some PC it is hard to get it running. The Cosmic compiler does work, but the constant license checking is really annoying; … and its error messages didn’t seem very clear to me either. And I haven’t even mentioned the main point: It doesn’t run on Linux!

tools %%

So, what to do? We will use OpenSource tools! What do we need?

  1. Development environment (IDE)
  2. Compiler
  3. Programmer/Flasher — software to upload the program to the chip
  4. Debugger

When I was putting all this together, this page helped me a lot, so you can take a look: https://github.com/hbendalibraham/stm8_started.

Pre-prepared Installation

I have prepared a teaching image of Devuan Linux, where everything is already set up and installed. So you don’t need to install everything manually, just:

  1. install VirtualBox
  2. install the Extension Pack into VirtualBox
  3. download the prepared image: Devuan-X-MIT.ova and import it.

A few notes about the image:

How to use VirtualBox and the prepared image:
MIT-Virtualbox

… but still read the text below so you know how to use it.

Toolchain

I have prepared a starting source code tree and Makefile.

https://gitlab.com/spseol/mit-no/STM8S-toolchain

This toolchain can be used on Linux, macOS and Windows. But it should be said that the toolchain is developed and primarily intended for Linux.

Installation

Watch out for SDCC version

In the SDCC compiler (regardless of OS), version 4.5.0 has a bug that makes it unusable for the STM8 platform. The bug is already fixed, but you need to be careful and install version 4.4.0 or a nightly build.

Linux

On Linux you call something like:

1
sudo apt install sdcc sdcc-libraries git make openocd
Installing SDCC from source code

Sometimes it happens that your distribution doesn’t have SDCC in the right version, or you want to install a nightly build. I use the program Stow for installing non-distribution packages.

1
sudo apt install stow

Libraries and dependencies needed for the build can be installed like this:

1
sudo apt build-dep sdcc

Then just download the source code, unpack and install:

1
2
3
4
5
6
7
cd sdcc-sources-4.5.12  # this is the name of the directory with the sources
./configure --prefix=/usr/local/stow/sdcc-4.5.12
make
sudo make install

cd /usr/local/stow
sudo stow sdcc-4.5.12

One small note: SDCC supports many different platforms that I don’t need. So my ./configure looks like this:

1
2
3
4
5
6
7
8
./configure --prefix=/usr/local/stow/sdcc-4.5.12 \
--disable-z180-port --disable-r2k-port --disable-r2ka-port --disable-r3ka-port \
--disable-gbz80-port --disable-tlcs90-port --disable-ez80_z80-port --disable-z80n-port \
--disable-ds390-port --disable-ds400-port --disable-pic14-port --disable-pic16-port \
--disable-hc08-port --disable-s08-port --disable-pdk13-port --disable-pdk14-port \
--disable-pdk15-port --disable-mos6502-port --disable-sm83-port --disable-f8-port \
--disable-mos65c02-port --disable-r800-port --disable-f8l-port --disable-r4k-port \
--disable-r5k-port --disable-r6k-port --disable-ez80-port

MacOS

On macOS it should be easy, because it is also Unix. Just use HomeBrew:

1
brew install open-ocd make git coreutils

Watch out for SDCC version 4.5.0! At the moment you need to build sdcc from source code.

So instead of…

1
brew install sdcc

download the source code, unpack it, and…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
brew install stow
cd sdcc-sources-4.5.12  # this is the name of the directory with the sources
export CPPFLAGS="-I/opt/homebrew/include"
export LDFLAGS="-L/opt/homebrew/lib"

./configure --prefix=/usr/local/stow/sdcc-4.5.12 \
--disable-z180-port --disable-r2k-port --disable-r2ka-port --disable-r3ka-port \
--disable-gbz80-port --disable-tlcs90-port --disable-ez80_z80-port --disable-z80n-port \
--disable-ds390-port --disable-ds400-port --disable-pic14-port --disable-pic16-port \
--disable-hc08-port --disable-s08-port --disable-pdk13-port --disable-pdk14-port \
--disable-pdk15-port --disable-mos6502-port --disable-sm83-port --disable-f8-port \
--disable-mos65c02-port --disable-r800-port --disable-f8l-port --disable-r4k-port \
--disable-r5k-port --disable-r6k-port --disable-ez80-port

make && sudo make install

cd /usr/local/stow/sdcc-4.5.12/
stow sdcc-4.5.12

sdcc -v

Windows

I spent a lot of time porting to Windows. But Microsoft throws quite a few obstacles in my way: I get it working — it works, an update comes — and I have to debug yet another problem. It just causes trouble and I have absolutely no motivation to fix it, because I don’t know when Microsoft will break my work again; and I haven’t even tried it on W11. Compilation is terribly slow. So my advice is:

Hint

If you really insist on Windows and have some good reason to use this underdeveloped OS, install VirtualBox and use the pre-prepared installation.

Nevertheless, at the moment it seems that the Toolchain does work on Windows, so if you are brave:

On Windows the easiest way to install is with Chocolatye:

1
2
3
choco install make git
choco install openocd
choco install vscodium  mingw

If you don’t have Python yet, you can also install Python:

choco install python

Bash is part of the Git package. On Windows it is also worth setting up Bash a little so it works well with make. So copy the configuration from .make/bashrc to the home directory.

1
cp .make/bashrc ~/.bashrc

SDCC installation must be done by clicking through the installer. You can download it here: https://sourceforge.net/projects/sdcc/files/sdcc-win64/

For flashing on Windows, STVP is used. If you have already installed STVD you already have STVP installed, because it is part of its installation. It can also be installed separately — without STVD.

Projects and SPL Library

The directory structure of individual projects looks like this:

MIT
├── Project-1
│   ├── inc
│   ├── lib
│   └── src
├── Project-blikblik
│   ├── inc
│   ├── lib
│   └── src
├── SPL
│   ├── inc
│   └── src
└── SPLSPL
    ├── inc
    └── src

Make a directory where all your projects will be — in the example above it is MIT. In the same directory there will also be directories named SPL and SPLSPL. In the SPL directories is the Standard Peripheral Library from ST. This library has quite a strange license and therefore I can’t just give it to you. You should find it and download it. Then you also need to apply a patch, which converts the library so it can be used with our SDCC compiler. The whole process is quite a lot of work, … but try typing make spl — maybe it will sort itself out.

Tip

Creating a project can be automated with a simple set of scripts available in the repository STM8S new project automation.

Further automation is available in the repository GitLab project interactive CLI, which can make creating a new project on GitLab much easier.

Usage

  • make spl — downloads and prepares libraries
  • make — compiles the project
  • make flash — uploads the program to the chip
  • make clean — deletes everything that was compiled
  • make rebuild — deletes everything and compiles again
  • make openocd — starts openocd for debugging
  • make debug — starts STM8-gdb

Competition :)

I should also mention that my colleague Wykys has also created a toolchain, which is much simpler and therefore easier to read:

https://gitlab.com/wykys/stm8-tools

Development Environment

I use Vim or rather Neovim. Not everyone likes this environment though, so as an editor and development environment I recommend VScodium/VScode.

Installation is described here.

Compilation

There are three Makefile files in the .make directory. This is because the SDCC compiler cannot remove dead code. There are about three solutions. The first is the most optimal; I kept the other two solutions just in case. When you call make for the first time, the toolchain switches to this most optimal solution called sdcc.

There are three Makefile files in the .make directory. Switching is done as a symlink Makefile in the root directory of the project.

1
2
$ ls -l Makefile
lrwx 1 mar 23 14. led 21.14 Makefile -> .make/Makefile-sdcc-gas

On strange systems that don’t support symlinks (such as Windows) it is hard-copied, so this operation can be destructive. Everything is prepared in the Makefile, so just call make.

1
2
3
    make switch-sdcc      # or
    make switch-sdccrm    # or
    make switch-sdcc-gas  # or

If you are not sure which one to choose, go with the first solution: SDCC

Solution 1: SDCC

SDCC - Small Device C Compiler is a compiler for various, more or less known 8-bit architectures. For STM8 it has one major disadvantage: it cannot remove unused code. What does this mean? Well… if you write everything yourself, it practically means nothing. But if you use some library (such as SPL), you will start to be bothered a lot, because the resulting machine code contains many functions that you compiled only because they were part of the library — not because you wanted to use them. These functions are not called anywhere and so the linker should remove them. And that is exactly what doesn’t happen :-( As a result, a program that could be about 2-3 kB ends up being 30 kB.

Fortunately there is one hack, which works roughly like this: The SPL library is split into small files (one function per file) and each is compiled as a separate module. These modules are made into a library, which the SDCC linker can already work with correctly. That is why the SPL library appears twice in the directory structure. SPLSPL stands for SPLit SPL and is used exactly for this.

Another solution to this problem is to use SDCC-gas or sdccrm described below.

Installing SDCC on Linux is fairly easy, because SDCC is part of most Linux distributions; so you call something like:

1
apt install sdcc sdcc-libraries

On Windows you download the installer and continue in the Windows-favourite way — by clicking.

Solution 2: SDCC-gas

https://github.com/XaviDCR92/sdcc-gas

Note

This solution is currently more of a historical leftover and in 98.45% of cases there is no need to deal with it. Feel free to read this section, but you probably won’t want to use this solution…

This is probably the best solution for optimizing (removing) dead code. It was created by adding support for GNU Assemblergas — into SDCC 3.9.0. gas is both the advantage and disadvantage of this solution. On one hand it means we can use classic tools from GNU binutils, on the other hand it means that those parts of sdcc-libraries written in STM8 assembly cannot be used and you need to use less optimal code written in C or rewrite the STM8 assembly into GNU assembler. …and occasionally it happens that some internal functionality (for example multiplication of 64-bit integers) is written only in STM8 assembler and you will have no choice but to work around it or rewrite that function in GNU assembler.

If you want to know more you can read here and here

This is the reason why in the sdcc-gas Makefile there are these lines:

1
2
3
4
SDCC_LIB_SRC_DIR = /usr/local/stow/sdcc-gas/share/sdcc/lib/src/
SDCC_LIB_SOURCE = _mullong.c _divulong.c _mulint.c _modsint.c
#SDCC_LIB_SOURCE  = $(notdir $(wildcard /usr/local/stow/sdcc-gas/share/sdcc/lib/src/_*.c))
SDCC_LIB_OBJECTS := $(addprefix $(OUTPUT_DIR)/, $(SDCC_LIB_SOURCE:.c=.o))

Any problems with missing functions can be fixed by adding the file name to the SDCC_LIB_SOURCE variable.

Build SDCC-gas

For everything to work you need to download the source code mentioned above and build it. I do it like this (I use Stow):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo apt install stow
sudo apt build-dep sdcc

cd sdcc-gas
./configure --prefix=/usr/local/stow/sdcc-gas
make
sudo make install

cd /usr/local/stow
sudo stow sdcc-gas

Build stm8-binutils-gdb

Note on version

The procedure described below is for the old version (GDB 8.1) from SourceForge. For the new version GDB 15.0 with improvements see the section Newer and nicer GDB v15.0 below.

You will use a similar procedure for the STM8 port of GNU binutils, which is needed for linking and debugging. I recommend using my version, which can be built even today with today’s Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
curl -fSL 'https://gitlab.com/spseol/mit-no/stm8-binutils-gdb-legacy/-/archive/main/stm8-binutils-gdb-legacy-main.tar.bz2?ref_type=heads' \
 |  tar xj
cd stm8-binutils-gdb-legacy-main//
export PREFIX=/usr/local/stow/stm8-binutils-gdb-legacy
./configure_binutils.sh
cd binutils-2.30+gdb-8.1-patched
make
sudo make install

cd /usr/local/stow
sudo stow  stm8-binutils-gdb-legacy

The compilation from source described above is theoretically possible on Windows too; in practice I have never tried it. Personally I would go (if someone forced me to use Windows) the route of Windows Subsystem for Linux. WSL 2 installation is very simple. Unfortunately USB cannot be natively connected in WSL — but it can be solved.

Solution 3: sdccrm

Note:

This solution is currently more of a historical leftover and in 99.974653% of cases there is no need to deal with it. Feel free to skip this chapter…

sdccrm is a dead code optimization tool for the STM8 SDCC port, which removes unused functions.

https://github.com/XaviDCR92/sdccrm

How does it work?: The code is first compiled to assembler by classic SDCC, then the unused code is removed using sdccrm, the whole process is completed and the code is converted from assembler to machine code.

It is a halfway solution: It works, the machine code is really smaller, but this option excludes the use of a debugger. Sometimes this may bother someone, other times it may not matter.

Also, you need to manually specify the functions you don’t want to “optimize” — meaning remove. So you need to watch error messages and enter the name of the missing function into the exclude_reference file inside the project directory.

Installation

sdccrm must be built from source code. It is a small program with no dependencies, so it can be compiled easily on Linux and on Windows — but just in case, a Windows binary is included in the toolchain in the file .make/sdccrm.exe.

On Windows:

1
choco install mingw

or on Linux:

1
apt install gcc

and then just:

1
2
cd sdccrm
make

Flashing

STVP

STVP is software from the chip manufacturer ST. It allows access to all parts of microcontroller memory. It has a graphical version and a command-line version. It is the command-line version that the toolchain mentioned here relies on.

OpenOCD

Open On-Chip Debugger is a tool for debugging and stepping through a program directly on the chip. openocd can also upload a program to the device memory. It works on Linux and Windows.

Installation on Linux is done with a simple command:

1
sudo apt install openocd

on Windows it is similarly simple thanks to Chocolatye.

1
choco install openocd

This is handled in the Makefile with the OPENOCD variable, so adjust it if needed.

To enable openocd to do simple flashing, you need to add a script that can do it. It is either part of the toolchain or you can add it to the end of the stm8s.cfg configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
proc program_device {filename flashstart} {
  halt
  wait_halt
  load_image $filename $flashstart
  sleep 10
  reset halt
  resume
  sleep 10
  shutdown
};

On Linux the full path might look like this: /usr/share/openocd/scripts/target/stm8s.cfg. If you installed on Windows using Chocolatye, it will most likely be this path: C:\ProgramData\chocolatey\lib\openocd\tools\OpenOCD-20190828-0.10.0\share\openocd\scripts\target\stm8s.cfg.

stm8flash

Another option is the program stm8flash. In most Linux distributions it needs to be built manually.

https://github.com/vdudouyt/stm8flash

1
2
3
4
5
6
sudo apt install pkg-config libusb-1.0-0-dev

git clone --depth 1 https://github.com/vdudouyt/stm8flash.git
cd stm8flash
make
sudo make install

Debugging

Communication with the chip via OpenOCD

openocdOpen On-Chip Debugger — is the tool we use to communicate with the chip and start/stop/step through the program. Installation was described in the Flashing section.

Start it like this:

1
openocd -f interface/stlink-dap.cfg -f target/stm8s.cfg -c "init" -c "reset halt"

Don’t worry, you don’t have to type this every time. It is written in the Makefile, so just call:

1
make openocd

STM8-GDB

GDB (GNU Debugger) is the standard tool for finding bugs in software. It allows you to stop the program, step through it, and look at variables while it runs — or even change them. For the STM8 platform you need the modified STM8-GDB from GNU binutils.

GDB is a text tool. My recommendation: don’t be put off and use GDB directly, or its lightweight wrapper cgdb. Both tools are described in detail in a separate article A small STM8-GDB course.

GDB mascot

A small STM8-GDB course

All other graphical tools use GDB as a backend. Their advantage and disadvantage is the GUI, which may be more attractive to many people, but on the other hand you may lose some features such as conditional breakpoints.

STM8 Debugger for vsCode/Codium

This is an extension directly for STM8, it also supports peripherals of some specific chips:

https://marketplace.visualstudio.com/items?itemName=CL.stm8-debug

Other VScode/Codium extensions

You can play around and try various extensions for VSCode/Codium. You will certainly need to edit the .vscode/launch.json file in the project and correctly link it with stm8-gdb.

Here is a list of a few extensions that might work. There are guides on the internet suggesting they do work. I personally never managed to get it running to my full satisfaction and I stick with my favourite cgdb. If you succeed, please let me know.

Here is also a draft of my .vscode/launch.json for Native Debug.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gdb-stm8",
            "type": "gdb",
            "request": "attach",
            "executable": "${workspaceRoot}/out.elf",
            "gdbpath": "stm8-gdb",
            "remote": true,
            "target": ":3333",
            "cwd": "${workspaceRoot}",
            "autorun": [
            ]
        }
    ]
}