Compiler Comparison
RTOS Availability
STM8AF LED Timer
STM8AF Serial
STM8AF Benchmarks
STM8AL LED Timer
STM8AL Serial
This short tutorial presents a simple "Hello World" program for the STMicroelectronics STEVAL-ISA164V1 board. The author used a Debian GNU/Linux system, but the tutorial should work for other Linux distributions, *BSD or other Unices.
The tools we use are
The STEVAL-ISA164V1 is connected to power and for the serial interface via the mini-USB port (we use the integrated USB-to-serial converter of the STEVAL-ISA164V1 board). To write our program to the board, an ST-LINK/V2 is attached to the SWIM port. The host computer is running a terminal program configured for 9600 baud, no parity, 8 bits, 1 stop bit and no flow control. We used gtkterm.
Depending on your operating system there might be an easy way to install SDCC 3.5.0 or newer using a package system or similar (e.g. apt-get install sdcc on Debian). While SDCC 3.4.0 should be sufficient for this tutorial, you might want to try a newer version in case you encounter any bugs. In particular, SDCC 3.4.0 has an issue with the library search path; this can be worked around by explicitly specifying the path to the standard library when linking.
SDCC binaries or a source tarball can be downloaded from its website.
The stm8flash source can be found at its GitHub location, where there is also a download link for a zip archive of the sources. To compile it, a C compiler, such as gcc, pkg-config and libusb need to be installed. Unzip the archive (e.g. using unzip stm8flash-master.zip) change into the directory stm8flash-master and type make
. In case there are any errors, such as header files not found, check that pkg-config and development files for libusb are installed.
We present a simple Demo that repeatedly outputs "Hello World!" on UART1. This demonstrates setting up and using the UART for serial I/O. Here is the C code:
// Source code under CC0 1.0 #include#include #define MSC_IOMXP0 (*(volatile uint8_t *)0x503a) #define CLK_CKDIVR (*(volatile uint8_t *)0x50c6) #define CLK_PCKENR1 (*(volatile uint8_t *)0x50c7) #define UART_SR (*(volatile uint8_t *)0x5230) #define UART_DR (*(volatile uint8_t *)0x5231) #define UART_BRR1 (*(volatile uint8_t *)0x5232) #define UART_BRR2 (*(volatile uint8_t *)0x5233) #define UART_CR2 (*(volatile uint8_t *)0x5235) #define UART_CR3 (*(volatile uint8_t *)0x5236) #define UART_CR2_TEN (1 << 3) #define UART_CR3_STOP2 (1 << 5) #define UART_CR3_STOP1 (1 << 4) #define UART_SR_TXE (1 << 7) int putchar(int c) { while(!(UART_SR & UART_SR_TXE)); UART_DR = c; return(c); } void main(void) { unsigned long i = 0; CLK_CKDIVR = 0x00; // Set the frequency to 16 MHz CLK_PCKENR1 = 0xff; // Enable peripherals MSC_IOMXP0 = 0x01; // Use pins 22, 23 for UART instead of GPIO. UART_CR2 = UART_CR2_TEN; // Allow TX and RX UART_CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2); // 1 stop bit UART_BRR2 = 0x03; UART_BRR1 = 0x68; // 9600 baud for(;;) { printf("Hello World!\n"); for(i = 0; i < 147456; i++); // Sleep } }
SDCC is a freestanding, not a hosted implemenatation of C, and allows main to return void. Note that in older versions of SDCC putchar()
takes char
and returns void
. This was not standard compliant has been changed in current SDCC versions.
The printf()
from the standard library uses putchar()
for output. Since putchar()
is device-specific we need to supply it. In this case we want it to output data using the USART.
The demo can be compiled simply by invocing SDCC using sdcc -mstm8 --std-c99 serial.c
assuming the C code is in serial.c. The option -mstm8
selects the target backend (stm8). An .ihx file with a name corresponding to the source file will be generated.
Assuming stm8flash and serial.ihx are in the same directory, the board is attached through an ST-Link/v2 device, ./stm8flash -c stlinkv2 -p stnrg388a -w serial.ihx
will write the demo onto the board. You can see the "Hello world" by using a terminal program configured for 9600 baud, no parity, 8 bits, 1 stop bit and no flow control.
stm8flash was written by Valentin Dudouyt. It works both with stlink (including the one integrated on the discovery boards) and stlinkv2 devices. The programmer can be selected using -c stlink
or -c stlinkv2
. The target device is selected using the -p
option (to get a list of target devices, use the -p
option with an option argument that is not an stm8 device, e.g. -p help
. stm8flash will treat filenames ending in .ihx
or .hex
as Intel hex, and other filenames as binaries.
SDCC was initially written by Sandeep Dutta for the MCS-51, and has a relatively conservative architecture (see Sandeep Dutta, "Anatomy of a Compiler", 2000). It has been extended by various contributors and more recently, incorporated some cutting-edge technologies, in particular in register allocation (see Philipp Klaus Krause, "Optimal Register Allocation in Polynomial Time", 2013). The stm8 backend was mostly written by Philipp Klaus Krause for his research into bytewise register allocation and spilling (see Philipp Klaus Krause, "Bytewise Register Allocation", 2015).
SDCC is a C compiler that aims to be compliant with the C standards.
Important compiler options for STM8 developers include:
-c
to compile into object files to be linked later--std-c99
for compilation in C99 mode (some C99 features, e.g. variable-length arrays are not yet supported in sdcc though)--opt-code-size
for optimization for code size--max-allocs-per-node
to select the optimization level. the default value is 3000. Higher values result in more optimized code, longer compiler runtime, and higher memory usage during compilation.