2014 April 12 13:20
Another Forth for the MSP430?
I’ve had an interesting week. Between Friday, April 4, and Friday, April 11, I worked feverishly to add support for TI’s MSP430 microcontroller to muforth. The work is not quite done, but I’m very pleased both with the results, and with how quickly it came together. During that time, I wrote:
- an assembler and a disassembler for MSP430 CPU instructions (but not for the CPUX extensions)
- host-side support for the chip’s bootstrap loader (BSL)
- a small debug stub (which I call “chat”)
- host-side support for chat (so I can read and write memory and registers, and execute code from muforth)
- support for writing to flash memory, both via the BSL and via chat
- an initial Forth kernel for the MSP430
What is currently missing is the rest of the kernel, and a working meta-compiler (sometimes called a cross- or target-compiler). Because the MSP430 instruction set is so well suited to Forth, building an indirect-threaded code (ITC) Forth is easy and efficient. NEXT is two instructions (two words) and four cycles. A call/return pair takes three words and eight cycles; so ITC is smaller, and faster by a factor of two!! Crazy.
ITC is elegant and beautiful, and is the perfect embodiment of Forth. I’m excited that it will work well on this chip!
Meta-compiling an ITC Forth is almost trivial, unlike meta-compiling native code. Finishing the meta-compiler is maybe one more day of work.
The rest of the kernel could take some time, depending on what I decide I want to add. A small multitasker? Fancy math support? Those are both probably coming, but the timeframe is unknown.
Why did I do it?
A friend was struggling to get his Launchpad to do much of anything. The debug story on the 430 Launchpad is pretty crazy. First, there is the TUSB3410 – an 8052 clone with a USB interface. This chip implements a USB CDC-ACM interface, bridging between the host and the serial (UART) port of a second chip – an MSP430F1612, which does some JTAG/Spy-Bi-Wire heavy lifting to talk to the target chip (in our case, an MSP430G2553). The protocol is, as far as I understand, undocumented, so we couldn’t easily just target that from muforth, which was my first thought.
Why not use the available tools? Well, they are Windows-only, for one. And they are also closed-source, limited (esp IAR Kickstart), and/or bloated (CodeComposer). We wanted to be able to talk to the chip from muforth, on Linux and OSX.
After reading about the target chip, we decided to target the BSL – a ROM-based bit-banged-serial bootstrap loader that is built-in to almost every MSP430 chip. We tossed out the Launchpad (figuratively, if not literally), breadboarded a G2553, tickled it into the BSL using jumper wires, connected an inexpensive USB-serial convertor, and tried talking to it from muforth. This took a few iterations – esp since, for all of this development, I have been writing code with no access to hardware!! To test, I push the code to my friend, he pulls and tries it out and tells me what happened. This would have been excruciatingly painful without audio chat, which we had going the entire time that we were debugging. Being able to talk hands-free while coding and brainstorming – to say nothing of fee-free! – was really liberating.
Once we could talk to the BSL, I wrote my chat stub, using my newly minted MSP430 assembler. Using the BSL, we copied this code to RAM and executed it, then switched some wires around – the BSL does not use the UART interface – we could talk via the chat protocol to the debug stub. Once I added a tiny piece of code to write a word to the flash memory, we could program the flash, and reboot into our own bootloader.
This all went suprprisingly well. At first we weren’t getting anything out of chat – but then quickly realized that we had forgot to switch the wires around, and also to change the serial port settings. The BSL runs at 9600 bps, with even parity. My chat runs at 115,200 bps, with no parity. Once we remembered to switch the wires and the host-side serial port settings, everything worked.
But why write another MSP430 Forth?
This work differs from other efforts that I’m aware of – such as CamelForth, 4e4th (German site) (English site), and mecrisp – by being a “tethered” Forth that compiles headless code – code without names – onto the target. This allows much bigger programs to fit into the flash. All the code to do the compiling and text processing is on the host, and leaving out the names saves a lot of space as well.
The MSP430G2553 – the chip that this work initially targets – has 16 KiB of flash. A lot of headless Forth code will fit into that space. ;-)
Read the 2013 journal.