Choosing Embedded Processors for AltOS

When Bdale and I started building rocketry hardware together, we had
already picked out a target processor, the TI
cc1111.
We picked that chip almost entirely based on the digital transceiver
that is built in to the chip, and not because we had any particular
love for the 8051 microcontroller. At that time, I'd seen people
struggle with PIC processors, battle AVR to a draw and spend a lot of
time trying to get various ARM processors running. So, the 8051 didn't
seem all that far from normal, and the cc1111 implementation of it is
pretty reasonable, including credible USB support and a built-in DMA
engine.

Since those early days, we've gone on to build boards with a slightly
wider range of processors:

TI cc1111

Atmel ATmega32U4

Atmel ATiny85

STMicroelectronics STM32L151/STM32L152

NXP LPC11U14

Bdale thinks we should reduce the number of components we use to focus
our efforts better. He's probably right, but I have to admit that I've
had way too much fun getting each of these chips running.

I thought I'd spend a bit of time describing our general process for
selecting a new CPU.

Free software. I'm long past the age at which I trust hardware
vendors to deliver credible binary software. If you want me to use
your silicon, make sure the tools required to use it are all free
software.

Debian support required. Bdale and I do everything on Debian, so
any processor we use needs to have tools that run under
Debian. We're more than willing to package software for Debian, so
if it's just generic Linux-compatible free software, that's fine.

Built-in USB. Everything we build needs to talk to a computer for
configuration and data download. Don't even think of asking me to
attach another chip for USB support. Ok, so the ATtiny85 doesn't
qualify here, and that project does use an external chip for USB
which is connected to the ATtiny85 through an LED and
phototransistor. I was excited when TI came out with the
CC340
chips because the MSP430 is a much nicer CPU than the 8051. But,
they still haven't added USB. If I'm going to add another chip for
USB, it'll be a CPU anyways, at which point I'll use a stand-alone
RF chip.

Cheap developer boards. TI sells a tiny little cc1111 developer
board; STmicroelectronics and NXP both sell boards that include a
programmer and a target CPU for prototyping software. And, there
are a million "Arduino" clones with various Atmel processors on
them. Cheap means I can buy them without thinking too hard; having
a built-in programmer means that early OS development can be done
without first having to figure out how to wire up a programmer.

Probably 32 bits, probably an ARM. Yeah, the cc1111 and Atmel
processors were fun to bring up, but I'm pretty much over the 8-bit
microcontroller now. ARM processors are far more sophisticated in
terms of power management and built-in device capability, plus
they're a ton faster at doing any math. The ATtiny85 remains an
exception here; it's smaller than any ARM I can get, and so it's
still useful for projects too small for an ARM.

Available in small quantities from a reasonable on-line retailer
like Digikey, Mouser or even Avnet Express. I'd love to try out the
new low-cost STM32L100 parts, but the only one available is the
largest one in the 64LQFP package, and I really don't need that
many pins for most products.

CC1111 involved a lot of software hacking

The 8051 processor in the CC1111 is very well documented, including
the two-wire debugging interface. What was missing was a canned
solution for programming and debugging the chip from Debian. However,
with sufficient motivation and accurate docs, I was able to create a
programmer from a USB device with a couple of GPIOs and a lot of ugly
software on Linux. That sufficed to get the USB stack limping along,
at which point I wrote a much faster programmer that ran on the cc1111
itself and could program another cc1111.

With that, I created an assembly-level debugger that could be hooked
to the existing SDCC source level debugger and had a full source-level
debugging environment for the 8051. This turned out to be way better
than what I could get on the Atmel processors, where I've got a
program loader and a whole lot of printf debugging.

STM has been great

The STM32L-Discovery board has a standard STM debugging setup for the
Cortex SWD interface right on the same board as a target CPU. That
made for completely self-contained development, with no jumper wires
(a first for me, for sure). There's free software,
stlink which can talk over the
debugger USB connection to drive the SWD interface. This is sufficient
to flash and debug applications using GDB.

Of course, GCC supports ARM quite well; the only hard part was
figuring out what to do for a C library. I settled on pdclib, which is
at least easy to understand, if not highly optimized for ARM.

We've built a ton of boards with the STM32L151 and STM32L152; at this
point I'm pretty darn comfortable with the architecture and our tool
chain.

Adventures with NXP

The NXP LPC11U14 is a very different beast. I'm using this because:

It's small (5mm x 5mm)

It's cheap ($1.48 q100)

The LPCXpresso board looks much like the STM32L-Discovery, with a
debugger interface wired to the CPU directly on the board. However, I
haven't found free software tools to drive this programmer; all I've
found are binary-only tools from NXP. No thanks.

Fortunately, the LPC11U14 uses exactly the same SWD interface as the
STM32L, so I was able to sever the link between the programmer and the
target on the LPCXpresso board and hook the target to an ST-Link
device (either the one on the STM32L-Discovery board, or the new
stand-along programming dongle I bought). With that, I wrote an
openocd script to talk to the LPC11U14 and was in business.

What I found in the NXP processor was a bit disturbing though --
there's a mask ROM that contains a boot loader, which always runs when
the chip starts, and a bunch of utility code, including the only
documented interface to programming the flash memory. I cannot fathom
why anyone thought this was a good idea -- I don't want a BIOS in my
embedded CPU, thankyouverymuch; I'd really like my code to be the
first instructions executed by the CPU. And, any embedded developer is
more than capable of programming flash using a register specification,
and calling some random embedded code in ROM from the middle of my
operating system is more than a bit scary.

NXP could do two simple things to make me like their parts a whole lot
more:

Publish the programmer source code. The programming dongle is a
tool for selling your silicon, not a separate revenue stream.
Publish the source under a free software license (GPL recommended,
of course). We'll take it, make it better, and ensure that you get
the changes back to help your other customers. It's a win-win plan.

Document the flash programming registers. Yeah, I could probably
disassemble the mask-rom bits that are on the chip, but I have
better things to do with my time. Heck, go wild and document any
other hidden bits in the silicon. Again, we're embedded developers,
we don't like magic hardware hidden from view any more than PC
developers like the BIOS and SMM.

Right now, I'm hoping the STM32L100C6 parts become available in small
quantities so I can try them out; they promise to be as cheap as the
LPC11U14, but are better supported by free software and offer more
complete hardware documentation. Yeah, they're a bit larger; that will
probably be annoying.