A Modern Forth IDE

Youtube Videos

https://www.youtube.com/watch?v=kDi-Nlz3-QA

https://www.youtube.com/watch?v=7DfeEcU-tAs

YouTube Demo Code

\ Program Name: ut-f0-disco-demo.fs
\ Date: Thu 29 Nov 2018 16:57:34 AEDT
\ Copyright 2018  t.porter <terry@tjporter.com.au>, licensed under a BSD Licence.
\ For Mecrisp-Stellaris by Matthias Koch. /
\ https://sourceforge.net/projects/mecrisp/
\ Chip: STM32F051, Board: STM32F0 Discovery Board
\ Clock: 8 Mhz using the internal STM32F051 RC clock, unless otherwise stated
\ All register names are CMSIS-SVD compliant
\ Note: gpio a,b,c,d,e, and uart1 are enabled by Mecrisp-Stellaris Core.
\
\ This Program : A simple 'Blinky' demo for You-Tube
\
\  This System is designed for a modified
\  /mecrisp-stellaris/mecrisp-stellaris-patches-and-kernels/
\  discof0-rtscts-480600-nlcr-green-blue-pc7cerror.bin kernel
\  This kernel sets the two leds as outputs for 'blue-on', 'green-on'
\  and 'blue-off', 'green-off'
\
\  Multitasking is in use see /library/f0-multitask.fs which is loaded last
\  Add 'pause' in looping words for good multitasking response.
\
\  Design program then click on the Gvim 'make' button to upload this program
\  to the target chip and run it.
\ ---------------------------------------------------------------------------\

 compiletoram
 f0-disco-48mhz


 0 variable counter
 1 variable flag

 : delay ( -- )                                         \ Non Blocking Delay
    counter @ 100000 = if
                 0 counter !
                 1 flag @ xor flag !
                    else counter @ 1+ counter !
                 then ;

 : leds-on-or-off?
      flag @ 0 =  if green-on blue-on
                    else green-off blue-off
                 then ;

 : main
      pause                                             \ essential Word
      delay
      leds-on-or-off? ;


 : init-general                                         \ essential Multitasking and Initialization Word
   f0-disco-48mhz ;

Want to know the meaning of the Words above ?

Historical Forth Development

Historically, Forth code was edited on a Host in a simple editor then uploaded to the Target Chip via a 9600 Baud serial terminal application such as Picocom or code was interactively entered directly into the serial terminal to interact in real time with the Target hardware. The basic design of Forth hasn’t changed much over the last 30 years and why would it?

Source-code uploads at 9600 Baud with only mk1-Eyeball code error checking was fine back in the day, but that day was 30 years ago.

One factor that still affects us today is that most Forths don’t have any communication handshaking between the terminal and the hardware, and where XON/XOFF software handshaking is available at one end, it must also be at the other. This situation is the same with hardware handshaking.

Note

Mecrisp-Stellaris does not come with communications handshaking either and the Picocom default serial terminal example syntax uses a end-of-line-delay to allow longer Words to be compiled without choking the on-chip compiler. This end-of-line-delay applies to all code including comments. I imagine this is a safe strategy so whilst comms may be slow, it doesn’t depend on a working handshaking configuration and the developer may later add handshaking if desired.

Modern Development Systems

Nowadays high level languages such as C running GGB via OpenOCD or SWD to the Target chip, are I believe, far more attractive to embedded developers than the historical Forth development, even if some of them such as the free Java based [atollic.studio] require a quad core PC with 32GB ram for a reasonable user experience.

C v/s Historical Forth

System Language Target Upload Speed Debugging Interactive Complexity Resources Header Files Libraries
Historical Forth Forth 9600 Baud slow yes low low minimal minimal
Atollic Studio C 2Mbits/s (swd) fast yes (GDB) very high quadcore PC yes yes

Coming from a C background, when I started using Forth I found the historical methods far too slow and error-prone for my taste and over the last three years have slowly developed a more modern Forth IDE that I believe is as fast, or faster than the C alternatives.

C v/s Modern Forth

System Language Target Upload Speed Debugging Interactive Complexity Resources Header Files ? Libraries
Modern Forth Forth 460800 Baud fast yes low Low - RPI yes (svd2forth) yes
Atollic Studio C 2Mbits/s (swd) fast yes (GDB) very high quadcore pc yes yes

Modern Forth IDE Elements

Description Software Reason for use
Serial terminal Gnu Screen Scriptable
Code editor Vim-Gtk Versatile and capable
Bourne Shell SH Common on all Unix systems
Coding/library support sfv2forth Automatically generate all Register and Bitfield memory mapped Words
Software Code Management Fossil Personal preference based on ease of use, capabilities and rock solid reliability.
Target Baud Rate increase to 460800 Mecrisp Kernel Mod 1 48x source-code upload speed increase
Hardware handshaking (RTS) Mecrisp Kernel Mod 2 Prevent the on-chip Forth Compiler from choking up
Automatic source-code error detection Mecrisp Kernel Mod 3 Stop the upload when a source-code error is encountered
Add CR to LF Mecrisp Kernel Mod 4 Stop ref:stair stepping<stair-stepping> on Gnu Screen

Serial Terminal: GnuScreen

In recent times, Forth developers have built custom serial terminals which include methods to speed up the development process. Examples of such serial terminals include E4thcom, Folie, Forth Explorer and others.

Custom serial terminals sometimes have these drawbacks:

  • are designed for a specific Forth and operating system
  • dependencies that don’t work properly on other operating systems
  • closed source

GnuScreen

Warning

Without RTS handshaking, (even at only 115200 Baud) a STM32F0xx at 48Mhz will probably choke on some Forth source code, resulting in the terminal ‘freezing’ until the Target is rebooted. This unsatisfactory situation can be worked around (until you impliment RTS handshaking for your MCU) by using the GnuScreen ‘slowpaste’ option.

Without RTS Handshaking

Note

you will probably have to change the serial device name to something other than my FreeBSD “/dev/cuaU0”

xterm -fs 12 -title 'GnuScreen@ 115200 bps | CTRL A :quit | ' -geometry 82x72+0+0 -e screen -t ProjectName -S ProjectName  /dev/cuaU0 115200 &

GnuScreen Slowpaste (msec)

GnuScreen has a Slow Paste Capabability. This adds a delay after each character in milliseconds.

  • Either

Enter this at the GnuScreen Terminal before each file you want to upload to the target.

<ctrl A> slowpaste 50
  • Or

Add this to your ~/.screenrc and make sure all instances of GnuScreen are killed before using it.

defslowpaste 50

With RTS Handshaking

Note

you will probably have to change the serial device name to something other than my FreeBSD “/dev/cuaU0”

xterm -fs 12 -title 'GnuScreen@ 115200 bps | CTRL A :quit | ' -geometry 82x72+0+0 -e screen -t ProjectName -S ProjectName  /dev/cuaU0 115200,crtscts &

Speedup Methods Employed

Issue Custom Serial Terminal Solution
end of line delay Parse the Forth receive data and wait for “OK” before uploading the next line of code
error detection Parse the Forth receive data and halt the source upload when one is encountered
comments Strip comments from the source before uploading them to the Target.
source-code sequencing The use of #include and #require commands inside Forth source-code files

Gnu Screen is unique in that it is easily scripted to provide serial communications. This means that it can be closely tied to a editor forming a kind of IDE freeing the programmer from entering/uploading/pasting source-code into a serial terminal and allowing the workflow to be editor based instead.

Issue Gnu-Screen Solution
end of line delay RTS Hardware handshaking
error detection Hardware handshaking from the Target chip Forth compiler which generates the error messages in the first place.
comments Strip comments from the source before uploading them to the Target.
source-code sequencing Source-code file positioning in the Project script file

Automatic Forth Command and File Uploading/sequencing

load-memmap.sh ...............................

#!/bin/sh
screen -p tm4c1294 -X stuff 'compiletoflash\n'
screen -p tm4c1294 -X readreg e pll.fs
screen -p tm4c1294 -X paste  e
screen -p tm4c1294 -X stuff '120MHz\n'
screen -p tm4c1294 -X readreg f memmap.fs
screen -p tm4c1294 -X paste  f
screen -p tm4c1294 -X stuff 'compiletoram\n'

load-memmap.sh ...............................

When “load-memmap.sh: is executed, the command “compiletoflash” is sent to the Target (as if it were typed into the terminal by hand), instructing it to compile Forth source-code into the Flash memory.

The source-code file “pll.fs” is then loaded into ‘register a’ and ‘register a’ is then ‘pasted’ (uploaded) to the Target at 460800 Baud, which is too fast to read on the GnuScreen terminal. Note that pll.fs is loaded first as it’s a dependency for the next file to be loaded.

There are 26 ‘registers’ available (a - z) to store and paste files if required.

The Forth Word “120MHz” (provided by “pll.fs”) is then executed, and increases the Target clock from 16MHz to 120 MHz so everything now happens 7.5 times faster.

memmap.fs is then uploaded and the Forth on-chip compiler is then switched back to compiling source-code into RAM.

At this point I can manually enter a command in the Gnu-Screen terminal such as “rcc.” and read the real time values in register ‘rcc’ on the Target chip itself.

rcc. RCC_CR () $00005383
            P             H H
            L P         C S S H                             H
            L L         S E E S                             S H
            R L         S B R E                             I S
            D O         O Y D O|    HSICAL     |         |  R I
            Y N         N P Y N|7:6:5:4:3:2:1:0| HSITRIM |  D O
           |2|2|       |1|1|1|1|1|1|1|1|1|1| | |4:3:2:1:0|  Y N
~|~|~|~|~|~|5|4|~|~|~|~|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|~|1|0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 1

Note

This scripting ability allows me to sequence the project build operations into a Makefile, so that when I click on the “Make” icon in the VIM-GTK toolbar, the upload and error checking are automatic just like in a modern C IDE tied to the Target via OpenOCD, Jtag, GDB or whatever.

Note

The creation and sequencing of project files is not done by hand, it’s done automatically by a ‘Project Builder’ (written in SH of course) which takes the name of a new project and then builds everything needed into a new directory of the same name.

Comment and Space Removal (RCAS)

Whilst extensive Forth source-code comments are vital for design and maintenance and blank lines aid readability, they mean nothing to the on-chip compiler, so before uploading the source-code file, we can strip all comments and empty lines. The source-code file is unaltered and upload time is decreased.

RCAS script code

Usage: rcas.sh <file>

# rcas.sh ................cut here....................

sed 's/\\.*$//g' < $1 | sed '/^\s*$/d' > $1.rcas.fs

# rcas.sh ................cut here....................

Rcas example with Gnu Screen

FILE_NAME=forthcode.fs

screen -p rcas -X readreg x `./rcas.sh $FILE_NAME` $FILE_NAME.rcas.fs
screen -p rcas -X paste x
rm $FILE_NAME.rcas.fs

Code editor

Vim-GTK or ‘gvim’ leverages the VIM editor and the GTK widget set to create a useful GUI editor. Of course any other editor with similar flexibility can be used.

Bourne Shell

Unlike Bash which is so common on Linux systems, the Bourne Shell (sh) is present of every Unix I have seen, so it’s a great compitability choice to provide the glue to tie everything together without needing to install yet another application.

Coding/library support

Modern Microprocessors such as ARM variants have a lot of peripherals, registers and register bit-fields, far too many for any coder to ever create memory mapped Words by hand. I wrote svd2forth to automatically derive Forth Words for Mecrisp-Stellaris from CMSIS-SVD system used by ARM, and this also forms part of the IDE.

Fossil SCM

Fossil is also integrated into my Project Builder so the new project automatically has its own SCM.

_images/fossil-1.jpg

Target Baud Rate increase to 480600

A simple Assembly Language Kernel hack to terminal.s in the Target chip directory of Mecrisp-Stellaris. This is nicely commented by Matthias, so just adjust the default value which provides 115200 Baud.

Hardware handshaking (RTS)

A simple Assembly Language Kernel hack to terminal.s in the Target chip directory of Mecrisp-Stellaris. This enables RTS hardware handshaking on USART1

Forth on-chip Compiler Hardware Handshaking

_images/f051-code-error-system-light.jpg

Automatic source-code error detection

Assembly Language addition to the Mecrisp-Stellaris source.

Logic analyser showing the Forth on-chip compiler CTS signaling on error

This shows the Forth on-chip compiler announcing a source-code error “is compile only” has been detected, then raising PC-7 which is connected to CTS. This halts serial communications with the PC at the actual source-code error.

_images/forth-code-error-raising-stm32f051-cts-internally.png

Add CR to LF

Assembly Language addition to the Mecrisp-Stellaris source.

For some reason Gnu-Screen (at least on my FreeBSD system) seems to ignore any configuration to stop ‘stair stepping’. The received data from the Forth system only contains a (Unix) line feed (LF) at the end of each line, but Gnu-Screen wants a DOS (LF/CR) pair. Rather than try and hack the Gnu-Screen source, I just added a carriage return (CR) to the existing (LF) in the Mecrisp-Stellaris Kernel.

To prevent ‘stair stepping’ when using GnuScreen on your version of Mecrisp-Stellaris Forth, grep the Mecrisp-Stellaris datastackandmacros.s file ( it’s in mecrisp-source/common/ ) for occurrences of

\Meldung\n

and replace them with

\Meldung\r\n

then rebuild the Mecrisp-Stellaris kernel and the GNUScreen stair stepping will be gone.