First Foray into FlashForth for AVR

Arduino-FVM was a nice, easy introduction to Forth on AVR/Arduino, and has a few advantages as a Forth implementation. But I was interested in something more developed and full-featured. So today I got FlashForth installed on a 328P MC, running on an Arduino Uno.

Installing FlashForth on AVR requires setting fuse bits as well as burning a new flash image, so I had to wire up my Nano ArduinoISP programmer again. Pulling this off required mixing details from the ArduinoISP tutorial, my previous post on ArduinoISP, and instructions from the FlashForth Web site, none of which were quite sufficient information taken individually.

I used the precompiled 328P hex flash image that is included in the FlashForth git repo. I intend at some point to compile the source, but I needed to get over the initial hurdle of seeing if I could get FlashForth to run on an MC at all, and if I liked it. This was the avrdude call which worked for me:

christopher@theoden ~/Repos/flashforth/avr/hex$ avrdude -p m328p -c stk500v1 -P /dev/ttyUSB0 -b 19200 -e -u -U flash:w:328-16MHz-38400.hex:i -U efuse:w:0xff:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "328-16MHz-38400.hex"
avrdude: writing flash (32524 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 32524 bytes of flash written
avrdude: verifying flash memory against 328-16MHz-38400.hex:
avrdude: load data flash data from input file 328-16MHz-38400.hex:
avrdude: input file 328-16MHz-38400.hex contains 32524 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 32524 bytes of flash verified
avrdude: reading input file "0xff"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xff:
avrdude: load data efuse data from input file 0xff:
avrdude: input file 0xff contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xda"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xda:
avrdude: load data hfuse data from input file 0xda:
avrdude: input file 0xda contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xff"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xff:
avrdude: load data lfuse data from input file 0xff:
avrdude: input file 0xff contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude done.  Thank you.

Here is the logon using picocom:

christopher@theoden ~/Repos/flashforth/avr/hex$ picocom -b 38400 -c /dev/ttyACM0picocom v3.1

port is        : /dev/ttyACM0
flowcontrol    : none
baudrate is    : 38400
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : yes
noinit is      : no
noreset is     : no
hangup is      : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,
logfile is     : none
initstring     : none
exit_after is  : not set
exit is        : no

Type [C-a] [C-h] to see available commands
Terminal ready
E FlashForth 5 ATmega328 18.11.2020

Here are the words defined by default:

words 
p2+ pc@ @p hi d. ud. d> d< d= d0< d0= dinvert d2* d2/ d- d+ dabs ?dnegate dnegate s>d rdrop endit next for in, inline repeat while again until begin then else if zfl pfl xa> >xa x>r dump .s words >pr .id ms ticks r0 s0 latest state bl 2- ['] -@ ; :noname : ] [ does> postpone create cr [char] ihere ( char ' lit abort" ?abort ?abort? abort prompt quit true false .st inlined immediate shb interpret 'source >in tiu tib ti# number? >number ud/mod ud* sign? digit? find immed? (f) c>n n>c @+ c@+ place cmove word parse \ /string source user base pad hp task ulink rsave bin hex decimal . u.r u. sign #> #s # digit <# hold up min max ?negate tuck nip / u*/mod u/ * u/mod um/mod um* 'key? 'key 'emit p++ p+ pc! p! p@ r>p !p>r !p u> u< > < = 0< 0= <> within +! 2/ 2* >body 2+ 1- 1+ negate invert xor or and - m+ + abs dup r@ r> >r rot over swap drop allot ." ," s" (s" type accept 1 umax umin spaces space 2swap 2dup 2drop 2! 2@ cf, chars char+ cells cell+ aligned align cell c, , here dp ram eeprom flash >< rp@ sp@ 2constant constant 2variable variable @ex execute key? key emit Fcy mtst scan skip n= rshift lshift mclr mset ic, i, operator iflush cwd wd- wd+ pause turnkey to is defer value fl+ fl- c! c@ @ a> ! >a literal int! ;i di ei ver warm empty rx0? rx0 tx0 load- load+ busy idle exit 
marker  ok<#,ram>

I only had a few minutes to experiment with it, but here are a several things of interest:

  • One great thing about FlashForth is that all the three memory types – RAM, flash, and EEPROM, are mapped to a contiguous address space, and accessible with @ and ! memory words. So, you don’t have to do anything special to write to flash or EEPROM.
  • By default, all words you add to the dictionary are compiled to flash memory and therefore survive a chip reset. This is very convenient.
  • You are not actually allowed to redefine words (at least, in the usual way of defining words), but you are expected instead to use the marker Forth word to construct forgettable sections of words. Also the empty word will remove all words but the core FlashForth words.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s