Go Forth and WikiReadit

WikiReaderThe WikiReader is a little $99 gizmo that lets you read Wikipedia. Yep, that’s all it does. No mobile phone, no movie player, no Webkit-enabled browser.

There’s something about a product that does one simple thing well. But what really sets the WikiReader apart is that it lasts a year on 2 AAA batteries with no charging. How? The low-power LCD screen, and the tiny microprocessor.

But what’s even cooler, at least for someone who learned to program by dabbling in Forth, is that the device has a built-in Forth interpreter for testing the hardware and running small programs.

I was pleasantly surprised – I know that Forth is good for embedded work on tiny micros, but since the main WikiReader app is written in C, I was curious why they chose Forth for testing and apps. So I asked Christopher Hall, one of the main firmware developers. His reply was very informative, and he’s kindly allowed me to copy it here:

I have written testing programs in several languages, but compiled programs always have the problem of the edit, cross compile, load, and try to debug. Sometimes the platform can run BSD or Linux, and then you can have the full suite of tools on the platform. This is okay if the person doing the initial testing can write programs, but often the test is how to toggle a particular I/O line on/off and see the effect on the rest of the circuit. Then having some kind of scripting on the platform seems the best way to achieve this.
For the initial testing, just start the interpreter REPL and you can start the initial tests. Initially I looked at TCL and Python which I have used before, but they would take far too long to port since they need a lot of Posix system calls which do not exist for this platform.
I also considered Hedgehog, Pico Lisp or perhaps some simple Scheme interpreter but the syntax would probably be too difficult for the hardware engineers to use. Forth is pretty simple syntax and RPN was probably not too difficult for them to learn. Also it was easy to build the Forth interpreter, incrementally adding features until it is now an almost ANSI standard Forth.
Since I added all the device registers the hardware engineers can use commands like the following (I used the same register names as the datasheet):
P0_P0D p?    \ display value of port
1 P0_P0D p!  \ set port to 1
While waiting for the main application development I could build tests for items like the LCD and CTP with just a serial connection on the device itself – using cut/paste from Emacs to picocom to upload Forth words. This is much quicker than cross-compiling and swapping SD cards.
The Forth is rather slow in compiling, the dictionary search is quite slow for example, and the indirect threading adds run-time overhead so in its present form it is probably not fast enough for the main reader application, but for quick applications to try things out I find it very convenient.
Also, the first version was hand translated from a version of EForth for Linux before I migrated it to the ANSI standard. (I kept copies in samo-lib/forth/EForthOriginals subdirectory.)

Very neat. If Lisp is the secret weapon for developing web apps, maybe Forth is it for embedded apps. Both are extensible at the language level and both have real macros, but Lisp is high level and Forth is low level.

Well, you know what to buy me for Christmas:

feeling-nice? if  WikiReader buy  then

4 December 2009 by Ben    5 comments

5 comments (oldest first)

Nickolai Leschov 5 Dec 2009, 02:55 link

I am exceted to hear about such thing! I think the world could use more souch things, that do one thing and do it well. I learned Forth in 2002 and managed to get paid for programming Forth back then; it was a joy.

Could you please clarify some things:

  • You say it uses 3 AAA batteries, their site says 2. Which is true?
  • How do I acess Forth interpreter? Do I need to connect to the device with a cable (no such thing seems to be included)? Or, wait, do I just type on the screen?
  • Is the code covered by some sort of open source license? (I suspect it is, but I didn’t see it mentioned.) How do I change the code running on the device or update to the newer release version? (It seems to be under active development.)
Ben 5 Dec 2009, 08:44 link

Hi Nickolai — out of interest, what company did you program Forth for? Thanks for the clarifications, too:

  • Good catch. Yes, it definitely runs on 2 batteries. Fixed now.
  • I don’t own a WikiReader (I wish), but this Arstechnica article says, “To access these programs, you hold the ‘random’ button down while you turn on the device. It will display a menu of the Forth programs and allow you to run one of them by tapping it on the touchscreen.”
  • As for licensing, browsing through the source tree shows that the main wiki app is licensed with the GPL, but the Forth is licensed with a BSD-style license. It looks like there are a couple of ways to update the source code, the easiest of which is by putting a file on the SD card.
Bob 6 Dec 2009, 02:51 link

I used Forth a great deal in the 1980’s. My last big Forth project was in 1995-6 — a system on a chip set top box decoder. We designed a 32 bit Forth oriented CPU in Verilog, and I wrote the cross assembler, cross compiler, simulator, operating system, and debugger. Too bad the chip was a bit too ambitious or its time, and the yeild out of fab was so low that they couldn’t make a profit with it.

Adam 8 Dec 2009, 10:29 link

I have one. I’m not even sure where to start with developing for it. I couldn’t get their toolchain going.

Carsten Strotmann 26 Mar 2010, 23:37 link

Hello Adam,

to start developing using Forth you do not need to have a toolchain. You can write and test a program using a Forth System on your PC (Linux or other OS), then you copy the source on the Micro-SD card in the Wikireader, and start executing. For debugging, you probably want to solder a serial terminal to the wikireader so that you can interactively develop and debug on thw wikireader itself (and not do cross-development, see http://wiki.github.com/wikireader/wikireader/hardware-specifications under “debug-connector”).