amforth (Forth for small AVR chips)
(Last updated 14 Oct 2010)

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.

Starting amforth

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 whatever).

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.

Programming errors

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.

I had forgotten how much fun these little beasts are to use.  A couple of chips, a Forth compiler, and I'm happy...