> What’s New ? <
Forth (embedded) Interactive Alternatives for Cortex M on STM32F¶
A quick look at other Open Source interactive development systems for Cortex M on STM32F, are they any good, do they even compete with Forth ?
Distribution |
Website |
Last Updated? |
Min Flash/Ram to run (KB) ? |
Run on Cortex M0 |
binary image tested |
Binary Image URL’s ? |
My conclusion ? Slower than Forth By —-> ? |
|
---|---|---|---|---|---|---|---|---|
Micropython |
current V1.1.1 |
256 16 |
No |
stm32f4disc-20170526-v1.9.dfu |
Stable, fast, seems well designed |
30x |
||
eLua |
current V0.9 |
260KB |
No |
elua_lua_stm32f407vg.bin |
Stable, fast, seems well designed |
? |
||
Armpit Scheme |
July 22, 2018 V070 |
60KB |
No |
armpit_060_STM32F4_Discov.bin |
<— |
Didn’t work for me when tested |
? |
Note
whilst not supporting STM32F**, uLisp looks to be a classy project, and definitely worth a visit: http://www.ulisp.com/. Speed tests have shown uLisp to be about 200x slower than Mecrisp-Stellaris
Micropython¶
MicroPython v1.9 on 2017-05-26; F4DISC with STM32F407
How does Micropython Work?¶
Micropython compiles the python source into bytecode, then the interpreter evaluates the bytecode. Using the Decorator it compiles typed python into assembly.
You can write functions in Arm assembly with the Decorator
Testing Micropython¶
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¶
Note
Micropython needs a Cortex M4 generally.
- Positives
Stable, fast, seems well designed
Documantation is excellent
Lots of libraries
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
The Flash Image I built was 309KB. The website ( https://micropython.org/) says “it is compact enough to fit and run within just 256k of code space and 16k of RAM”. By Contrast Mecrisp-Stellaris only requires a Flash image of 20KB, making it perfect for inexpensive MCUS with as little as 32KB Flash.
For some reason the Micropython home website ( https://github.com/micropython/micropython) does not offer any prebuilt binary images.
Garbage collection is required which means that there will be delay while this is done, possibly a few mS, making this non real time.
Manual testing is tedious due to the language constraints, I’ve been spoilt by Forth.
My thanks to Per Ljung for updates and information re Micropython, and Vincent Hamp for taking the time to point out a major typo.
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
Stable, fast, seems well designed
Documantation is very good
eLua has a online image builder for 21 targets (http://builder.eluaproject.net/web/start.lua?control=builder&act=index free registration required) but sadly it didn’t have a STM32F4 Discovery build option when I tried it, and there is no binary available on the hompage. A binary has bene built and is available from this url: http://stm32f4.web.fc2.com/elua.html
- Not so positives
File upload is via Xmodem, which is painful with Minicom, but there are probably better ways.
Requires a 260KB Flash image, this makes it unusable on any MCU with less than 512KB 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.
Manual testing is tedious like Micropython due to the language requirements
Armpit Scheme¶
Armpit Scheme is an interpreter for the Scheme language (lexically-scoped dialect of Lisp) that runs on RISC microcontrollers with ARM core. The website has a very neat and academic look and feel.
Armpit scheme looked promising when installed on a stm32f4 discovery, but only partially ran. It’s also available for a tm4c1294xl which I haven’t tried yet.
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.