-
Notifications
You must be signed in to change notification settings - Fork 66
STM8 eForth Programming Tools
Interacting with the STM8 eForth console typically requires a serial terminal program like e4thcom (the "official" terminal for STM8 eForth - more about that below), picocom, miniterm, cutecom... for Windows HyperTerminal or any alternative. Even a vintage 70s "dumb terminal" can be used.
The serial connection uses the UART_TX
and UART_RX
pins - for an STM8S that's typically PD5
and PD6
but the STM8L families use different GPIOs, some devices can do remapping, and STM8S and STM8L High Density variants offer two or more serial interface. Please refer to the descriptions in the README.md of the board and base image configuration folders.
STM8 eForth can simulate a 3-wire or a 2-wire serial connection with GPIO change- and TIM4 interrupts (see below).
It's also possible to connect an alphanumeric display and a keyboard directly - maybe a "retro computing" project tries to do that one day.
Note: at least on STM8 Low Density devices with 1KiB RAM there isn't enough space to support a disk block buffer for source code: the only source code storage in STM8 eForth is a 80 bytes line buffer, and backspace (^h
) is the only editing feature. STM8 Medium and High Density devices have enough RAM to store at least one "screen buffer" (i.e. 64x16 chars, 1 KiB), and they have the potential to support a Forth file system. High Density devices offer from 32K to 96K of "far memory" Flash ROM - using some compression that's almost the equivalent of an 80s single-sided floppy disk, although the far memory would be a good fit for a linked-lists of text blocks.
STM8 eForth uses a serial interface (or any other character I/O device that you provide) for the interactive console. Typically, STM8 eForth source code will be stored on a host computer, and transferred to the embedded system.
This can be done with the following tools:
Tool | Description | Features |
---|---|---|
e4thcom | The "official" STM8 eForth interactive terminal provides an STM8EF plugin (linux) |
#include , #require , res , \\ , synchronization. |
codeload.py | A command line tool for non-interactive programming and automated testing |
#include , #require , res , \\ , synchronization |
simload.sh | A command line tool for automated testing and code generation using uCsim |
#include , #require , res , \\ , synchronization |
ascii-xfr | Picoterm standard ASCII upload plug-in with flat files, no synchronization, slow | none |
generic terminal | most terminal programs provide a text transfer feature with line delay, no synchronization, slow | none |
e4thcom
is a terminal program for embedded Forth systems, e.g. noForth, AmForth, and Mecrisp with a line editor, a line history, and conditional/direct source upload. X86 Linux and Raspberry Pi binaries are provided (there have been attempts to support Window10 WSL). From release v2.2.15 STM8 eForth uses the e4thcom
transfer method, which is also supported by codeload.py
in the tools
folder.
When starting e4thcom from the Linux command line several parameters need to be passed, e.g. e4thcom-0.6.2/e4thcom-0.6.2 -t stm8ef -d ttyUSB0
. This is simplified by an STM8 eForth Makefile target: running make term
sets default parameters and starts e4thcom. A viable solution for selecting an e4thcom binary release is placing a symlink to the e4thcom binary in a folder that's in the search path (e.g. /usr/local/bin/e4thcom
).
As a Forth system e4thcom
interprets some user inputs from the keyboard or from a file input stream and thus adds some nifty features, some of which are currently not publicly undocumented (e.g. it can run a target system assembler). e4thcom starts in interactive mode, \
at the beginning of a line initiates the terminal control mode (\
alone closes e4thcom). #i
and #r
are short forms for #include
and #require
). These commands, followed by the name of a source file, bring the terminal into the non-interactive transfer mode.
The method endorsed by STM8 eForth relies heavily on the following e4thcom keywords:
Keyword | file/interactive | description |
---|---|---|
\res MCU: <file> |
file | preload the contents <file>.efr from the mcu folder |
\res export <name> |
file | export <name> from a preloaded efr-file as a CONSTANT
|
\\ |
file | treat the rest of the file as a comment (i.e. don't transfer it to the target) |
#include <name> |
both | transfer the file <name> in the search path |
#require <name> |
both | test if the word <name> is in current dictionary, otherwise transfer the file <name> in the search path |
#ifdef <name> |
file | interpret the rest of the line if the word <name> is in the dictionary |
#ifndef <name> |
file | interpret the rest of the line if the word <name> isn't in the dictionary |
Here is an STM8 eForth source file example with e4thcom keywords:
#include hw/pd8544.fs \ unconditional uploading
#require ALIAS \ conditional uploading if the word ALIAS isn't in the dictionary
\res MCU: STM8S103 \ use the STM8S103.efr symbol/address file
\ get GPIO registers addresses, insert definitions like `hex 5000 CONSTANT PA_ODR`
\res export PA_ODR PA_IDR PA_DDR PA_CR1 PA_CR2
#ifndef OUT! \res export PB_ODR
#ifndef OUT! : OUT! ( f -- ) PB_ODR 4 B! ;
\\ ignore the rest
of the file
The e4thcom conditional upload feature in #require
and \res export
checks for the presents of a word equal to <filename>
(e.g. ]C!
), and uploads the file only if it's not already in the dictionary. After successful it tests again, and creates a dummy word corresponding to the filename, if no such word is in the dictionary.
Filenames must not contain whitespace characters, and under Linux the character /
(forward slash) is forbidden. Under Windows, a long list of reserved characters and filenames applies.
Source files can include (or #require) other source files.
e4thcom
has a defined search path order for include files: normally the search is done in the order cwd:cwd/mcu:cwd/target:cwd/lib
(cwd
or .
is the directory from which e4thcom was started) but this can be modified by parameters.
The author suggests the following organization for source code:
-
cwd
project sources -
cwd/lib
STM8 eForth library -
cwd/target
symlink toout/<board>/target
-
cwd/mcu
hardware-specific words
The folders can be created and populated by downloading a binary release and creating a symlink to out/<board>/target
. The W1209 Makefile automates this (i.e. run make target
).
The conditional directives #ifdef
and #ifndef
(new in e4thcom 0.8.5) use the same conditional feature as #require
or \res export
but they act on the rest of the source file line. The example above demonstrates a method to interact with the target on a level below "dictionary - source file". The main application for this feature is dealing with device variants in hardware drivers: it's possible to "negotiate" with the target system which action to take.
Please refer to the documentation provided on the e4thcom page.
The command line tool codeload.py
emulates the code transfer and conditional features of e4thcom described in the last chapter but it offers some more options for automation. It can be used with the serial interface (using pySerial) and UART emulation of uCsim using telnet, and it's intended to work with the same source files, search directories, and \res MCU: ... \res export
directives as e4thcom. It depends on Python3 but a Python 2.7 version is still available.
thomas@w500:~/source/stm8s/stm8ef$ tools/codeload.py -h
usage: codeload.py [-h] [-b base] [-p port] [-r rate] [-q] [-t tracefile]
{serial,telnet,dryrun} [files [files ...]]
positional arguments:
{serial,telnet,dryrun}
transfer method
files name of one or more files to transfer
optional arguments:
-h, --help show this help message and exit
-b base, --target-base base
target base folder, default: ./
-p port, --port port PORT for transfer, default: /dev/ttyUSB0,
localhost:10000
-r rate, --rate rate RATE for serial transfer, default: 9600
-q, --quiet don't print status messages to stdout
-t tracefile, --trace tracefile
write source code (with includes) to tracefile
codeload.py
is a core part of the STM8 eForth Continous Integration framework: it can be used to load main.fs
or board.fs
and run automated tests or install code for periphery support.
Note that codeload.py
is intended to be platform independent but up to bbf69e1 the author only used it on Linux x86-64. Please file an issue if you have new test results, e.g. on MAC or Windows (negative as well as positive).
In order to support build and test automation simload.sh
wraps uCsim and codeload.py
.
It accepts a board name as a parameter, and performs the following actions:
- load the board's binary file (
out\<BOARD>\<BOARD>.ihx
) into uCsim - set a breakpoint at
HI
and patch the communication routines to use plain UART I/O - transfer the Forth code in
main.fs
or, if not present, in<BOARD>/board.fs
usingcodeload.py
The recommended execution environment for simload.sh
is tg9541/docker-sdcc.
The following picocom wrapper works for full-duplex and wired-or half-duplex with implicit echo (e.g. W1209). It also sets a suitable line delay for programming Forth to NVM without handshake:
#!/bin/sh
# "$@" --imap lfcrlf --emap crcrlf --omap delbs \
exec picocom \
--send-cmd="ascii-xfr -s -c10 -l500" \
"$@" --imap igncr,lfcrlf --omap delbs \
/dev/ttyUSB0
Normally the Forth console uses the STM8 UART as a 3-wire interfaces (Rx, Tx and GND) in full-duplex mode. Alternatively STM8 eForth can be configured to "half-duplex" mode where it sends and receives through a 2-wire interface (shared Rx/TX-pin and GND).
The STM8 UART provides native support for 2-wire half-duplex, and for STM8 Low Density Devices the binary STM8S001J3
implements this interface configuration (it also works for e.g. STM8S003F3, STM8S903K3, etc).
For boards that don't offer access to UART pins the generic binary SWIMCOM
can be used (for 2-wire communication PD1 on the SWIM ICP header is the default but any other GPIO that supports interrupts can be configured in globconf.inc
).
The following simple wired-or interface can be used to interface an STM8 2-wire interface to a PC UART converter:
STM8 device . .----o serial TxD "TTL"
. | (e.g. "PL2303 USB serial converter")
. ---
. / \ 1N4148
. ---
. |
STM8 PD1/SWIM-->>-----*----o serial RxD "TTL"
.
GND------------>>----------o serial GND
.
................
Common USB interface chips are known to work well (e.g. CH340, CP2102 or PL2303). Please note that a common type of CH340 USB serial converters has a 1k5 resistor in series with the TxD signal which makes it unreliable. Refer to issue #269 for additional information.