> What’s New ? <

Forth (embedded) Interactive Alternatives On Cortex M

A quick look at other Open Source interactive development systems for Cortex M, are they any good, do they even compete with Forth ?

Distribution Website Last Updated? Flash Image Size Run on Cortex M0 with 32KB flash ? binary image tested Binary Image Website ? My conclusion ?
Micropython https://micropython.org/ current 309KB No stm32f4disc-20170526-v1.9.dfu http://micropython.org/resources/firmware/ Stable, fast, seems well designed
eLua http://www.eluaproject.net not dead, but lethargic 260KB No elua_lua_stm32f407vg.bin http://stm32f4.web.fc2.com/elua.html Stable, fast, seems well designed
Armpit Scheme http://armpit.sourceforge.net/ December 5, 2014 60KB No armpit_060_STM32F4_Discov.bin <— Doesn’t work

Micropython

MicroPython v1.9 on 2017-05-26; F4DISC with STM32F407

I installed the stm32f4disc-20170526-v1.9.dfu image on a STM32F4 Discovery following the tutorial at https://github.com/micropython/micropython/wiki/Board-STM32F407-Discovery, which went very smoothly and quickly.

The Micropython bulk USB storage device mounted easily with the Micropython files visible and the terminal was fast and bugfree using Picocom on Linux (freeBSD was buggy however).

Micropython Terminal demo

>>> help()
Welcome to MicroPython!

For online help please visit http://micropython.org/help/.

Quick overview of commands for the board:
 pyb.info()    -- print some general information
 pyb.delay(n)  -- wait for n milliseconds
 pyb.millis()  -- get number of milliseconds since hard reset
 pyb.Switch()  -- create a switch object
                  Switch methods: (), callback(f)
 pyb.LED(n)    -- create an LED object for LED n (n=1,2,3,4)
                  LED methods: on(), off(), toggle(), intensity(<n>)
 pyb.Pin(pin)  -- get a pin, eg pyb.Pin('X1')
 pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p
                  Pin methods: init(..), value([v]), high(), low()
 pyb.ExtInt(pin, m, p, callback) -- create an external interrupt object
 pyb.ADC(pin)  -- make an analog object from a pin
                  ADC methods: read(), read_timed(buf, freq)
 pyb.DAC(port) -- make a DAC object
                  DAC methods: triangle(freq), write(n), write_timed(buf, freq)
 pyb.RTC()     -- make an RTC object; methods: datetime([val])
 pyb.rng()     -- get a 30-bit hardware random number
 pyb.Servo(n)  -- create Servo object for servo n (n=1,2,3,4)
                  Servo methods: calibration(..), angle([x, [t]]), speed([x, [t]])
 pyb.Accel()   -- create an Accelerometer object
                  Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()

Pins are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name
Pin IO modes are: pyb.Pin.IN, pyb.Pin.OUT_PP, pyb.Pin.OUT_OD
Pin pull modes are: pyb.Pin.PULL_NONE, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN
Additional serial bus objects: pyb.I2C(n), pyb.SPI(n), pyb.UART(n)

Control commands:
 CTRL-A        -- on a blank line, enter raw REPL mode
 CTRL-B        -- on a blank line, enter normal REPL mode
 CTRL-C        -- interrupt a running program
 CTRL-D        -- on a blank line, do a soft reset of the board
 CTRL-E        -- on a blank line, enter paste mode

For further help on a specific object, type help(obj)
For a list of available modules, type help('modules')
>>>

STM32F4 Discovery led tests

>>> led2 = pyb.LED(2)
>>> led2.on()          <-- the board led 2 turned on
>>> led2.off()         <-- the board led 2 turned off

>>>  led2.toggle()     <-- toggles the led!

Conclusion

  • Positives
    • Stable, fast, seems well designed
    • Documantation is excellent
    • Lots of libraries
    • Needs a Cortex M4 generally. M0 is not supported (see Circuit Python, Micropython fork for Atmel SAMD21, Cortex M0 support)
    • The CTRL-E serial terminal “paste mode”, which is just like a rock solid full screen editor is just awesome, I want one for Forth too!
  • Not so positives
    • manual testing is tedious due to the language constraints, I’ve been spoilt by Forth.
    • Requires a 309KB Flash image, this makes it unusable on any MCU with less than 1GB Flash. By Contrast Mecrisp-Stellaris only requires a Flash image of 20KB, making it perfect for inexpensive MCUS with as little as 32KB Flash.
    • Garbage collection is required which means that there will be delay while this is done, possibly a few mS, making this non real time.

eLua

The binary flashed to a STM32F407VG Discovery easily using st-flash as below:- st-flash write elua_lua_stm32f407vg.bin 0x08000000

Then a terminal was connected at 115200 Baud, 8,n,1.

picocom -b 115200 /dev/cuaU20

Terminal Board
TX PD-9
RX PD-8

eLua Terminal demo

eLua# ver
eLua version v0.8
For more information visit www.eluaproject.net and wiki.eluaproject.net

eLua# help
Shell commands:
 exit        - exit from this shell
 help        - print this help
 ls or dir   - lists filesystems files and sizes
 cat or type - lists file contents
 lua [args]  - run Lua with the given arguments
 recv [path] - receive a file via XMODEM. If path is given save it there, otherwise run it.
 cp <src> <dst> - copy source file 'src' to 'dst'
 wofmt       - format the internal WOFS
 ed  [args]  - run 'ed' text editor with the given arguments
 ver         - print eLua versio

 eLua# lua /rom/info.lua
 Press CTRL+Z to exit Lua
 I'm running on platform STM32F4
 The CPU is a STM32F407VG
 The board name is STM32F4DSCY

 eLua# lua
 Press CTRL+Z to exit Lua
 Lua 5.1.4  Copyright (C) 1994-2011 Lua.org, PUC-Rio
 > print ( 355 / 113.0)
 3.141592920354

 > print ( math.sin(355/113/2))
 0.99999999999999

eLua Blinky

The following program based on a eLua example file was loaded, and the board led blinked nicely.

-- eLua blinking led example, the Hello World of embedded :)

local uartid, invert, ledpin = 0, false

-- STM32F4 Discovery
 ledpin = pio.PD_13
 uartid = uart.CDC

function cycle()
 if not invert then
   pio.pin.sethigh( ledpin )
 else
   pio.pin.setlow( ledpin )
 end
 tmr.delay( 0, 500000 )
 if not invert then
   pio.pin.setlow( ledpin )
 else
   pio.pin.sethigh( ledpin )
 end
 tmr.delay( 0, 500000 )
end

pio.pin.setdir( pio.OUTPUT, ledpin )
print( "Hello from eLua on STM32F4 Discovery" )
print "Watch the red led blinking :)"
print "Press the Disco Reset Button to end this demo.\n"

while 1
do  cycle()
end

Conclusion

  • Positives
  • Not so positives
    • File upload is via Xmodem, which is painful with Minicom, but there are probably better ways.
    • manual testing is tedious like Micropython due to the language requirements.
    • Requires a 260KB Flash image, this makes it unusable on any MCU with less than 1GB Flash. By Contrast Mecrisp-Stellaris only requires a Flash image of 20KB, making it perfect for inexpensive MCUS with as little as 32KB Flash.
    • Garbage collection is required which means that there will be delay while this is done, possibly a few mS, making this non real time.

Armpit Scheme

This looked promising when installed on a STM32F4 Discovery, but only partially ran.

Summary

I would have been interested in Micropython if I hadn’t already seen the Forth light a few years ago.

For instance, if I want to turn a led on or off with Forth, I’ll make a ‘lon’ and ‘loff’ Word that I use during manual testing, and change it to something like ‘overspeed-indicator-led-on’ (or off) when it’s debugged and part of a lower level Word where the naming is everything.

With Microptyhon I’d find ‘l.on()’ and ‘l.off()’ too tedious for on the fly manual typing during testing as it involves double the keys and two shifts. I’d be trapped in a non extensible language again where the problem solution still looks like the same language I started with.

I’m a hardware guy, I’ll have the keyboard balanced on the scope, trying to avoid the hot soldering iron and my coffee as I’m developing, so I want the most for the least when I type.

eLua on Cortex M4 is not a bad effort either, but requires similar resources to Micropython.

Armpit-Scheme is still dead and stuck in 2014.

In summary, I can only find two competitors for Forth, and neither of them will even run on any MCU with less than 256K Flash.

Not to mention lack of speed, ram usage, garbage collection issues and so on ...

In the small embedded end of the market, this means that Forth really has no interactive competitors, so nothing has changed that I can see.