I have been working with the amforth Dev
team for a while now and wanted to put in a plug for what I think is a
way cool project. amforth, originally developed by Matthias
Trute, is a Sourceforge project that provides a near-ans94 compliant
Forth in about 10 KB of code space. (Actually, you can customize
amforth as you like and get the footprint to below 8 KB.)
I have a long history with Forth and have written several Forth
compilers for various machines, so I jumped at the chance to try out
Matthias' project. I downloaded the source files, created an
AVRStudio4 project, and wrote a small template file describing the
contents of the Forth system I wanted. I assembled the whole
pile, burned it into a small ATmega328P project board I had laying
around, and hooked up my PC (running TeraTerm) to the project board's
RS-232 port. When I hit the power, I had Forth running!
Refer to the obligatory screen shot below.
The Forth system, and any words I compile, are saved in low flash
memory, which means my applications are non-volatile. The source
for any amforth words I write must live on the host PC and are sent
over the serial port as ASCII text. So compiling any large Forth
words involves a file transfer from TeraTerm (or Hyperterm or
I found the procedure for setting up the source files and AVRStudio4
project a bit confusing, so I wrote an amforth User's Guide that I hope
clarifies the setup. That document is now part of the amforth
distribution. I recently (Oct 2010) updated the document to
reflect some of
the advances in version 4.2 of amforth.
I find it cool to have an interactive development system, with
compiler, living on the target hardware; this is an aspect of Forth
I've always loved. The ability to poke the hardware
interactively, then add your design changes to local source and compile
to native code is just plain fun (and productive), in ways that I don't
get with the conventional C programming model.
However, there are a couple of issues with amforth that you need to be
aware of going in. I don't consider these to be show-stoppers,
and the amforth Dev community is addressing them, but you need to know
about them if you want to get the most out of amforth.
amforth burns each newly created word into flash memory. This
means that as you download the source for your new Forth words, the
Forth kernel is constantly writing to flash, which takes time.
There is no handshaking built into the file transfer operation in
amforth, so you have to send the source text V-E-R-Y --
S-L-O-W-L-Y so you don't overrun the kernel. I usually set up
TeraTerm with a 20 msec delay between characters and a 700 msec delay
after each line. This makes for a very slow download, but
improves the chances of a successful load.
If you manage to outrun the kernel, the kernel will report an error
because one of the definitions got mangled. However, the kernel
can't stop the flow of text and it will begin trying to execute the
rest of the incoming text as if you were typing it in. This is
terribly wrong and usually results in damage to some of amforth's
internal variables, which in turn yields an unresponsive system.
The only way to recover is to reload amforth's EEPROM data, the
amforth kernel in flash, or both.
This means amforth is not very friendly for beginners. Ideally,
you should be able to hand over a board with amforth installed and not
ever have to connect a programming dongle again. amforth's
current download mechanism isn't that robust yet. For now, keep
the download configuration as above and you will probably be OK.
Yup, we all make them, and Forth's interactive nature is a double-edged
sword. For example, lose track of the stack contents, store where
you shouldn't, and the next thing you know, you've lanced something
vital in amforth's innards. When that happens, you are back to
the situation described above. You have an unresponsive system
that requires a programming dongle and firmware download to fix.
For now, you simply have to reload the firmware or EEPROM image.
There are plans in the works (by me, and I'm sure by others) to avoid
having to go back to the programming dongle.
Fixes and plans
One possible solution to the above problems is to keep a copy of the
EEPROM and flash images in some off-chip non-volatile memory, such as
serial EEPROM. If the system gets corrupted, reset the system and
use code in the bootloader section to refresh the amforth images from
serial EEPROM. I am currently working on adding a Microchip
25LC512 to hold the amforth images so I can refresh the '328P's
firmware when needed.
Because the 'LC512 holds 64 KB of data, it has enough room for a large
amforth image with room left over for source files. I am also
working on a simple editor and file system for the serial EEPROM.
If this works the way I expect, the downloads will be all but
unnecessary and the source files can be developed on the target, using
TeraTerm as an editing console.
Carry this one step further and connect amforth's kernel to an LCD
screen and a keyboard of some kind (PS2 or switch matrix). Now
you have a self-contained development system that can run off a set of
penlight batteries, be built into a small and rugged enclosure, and be
used for embedded development literally anywhere in the world.