Computing stuff tied to the physical world

A µC is just a small computer

Ok, so let’s take the position that an embedded µC is “just another computer” for now, albeit dramatically more limited than the ones driving today’s laptops and desktops.

Now we want to write software for it. We can’t load a compiler onto the µC, but we can use a “cross-compiler”, which runs on our “big” computer and generates code for our little µC.

For decades, C/C++ has been the language of choice for this task. For decades, this meant purchasing a proprietary compiler which “targets” our specific brand of µC. But no more. Now, we can use “gcc” as open source toolchain for just about any µC under the sun.

Integrated Development Environments

The Arduino IDE needs no introduction (well, perhaps this one). It wraps a simple editor, the gcc tools, an uploader (avrdude), and a serial console into a convenient executable.

For TI’s ARM chips, there’s a derivative of the Arduino IDE, called Energia.

For NXP’s LPC ARM chips, there’s LPCxpresso, based on the Eclipse IDE.

The above environments are available for Windows, Mac OSX, and Linux. Many more editor/compiler solutions exists for specific host-platform + target-chip combinations.

The MBED online compiler offers another path, and is portable since it’s browser based.

Ide s

Reusing other people’s code

Each of these, in particular the Arduino-centric IDEs, come with a large set of libraries and an even larger range of open source libraries, contributed by their respective communities. This is a mixed blessing, as they don’t always mix-and-match, and sometimes their quality or level of use & support cannot be determined easily. Trial-and-error may be needed.

Libraries vary greatly in purpose and generality. They are, after all, just that: collections of code, organised in such a way to that they can be reused in other projects, and by others. There’s an ever-recurring trade-off between finding existing (solid!) code, extending that code if needed, or starting from scratch plus having to figure out everything ourselves.

As a virtually unlimited resource of open-source projects, there’s always GitHub. Here are a few libraries which cover a lot of ground in many different ways: PlatformIO (portable), stm32plus (STM32, C++ templates), and Cosa (AVR, OO). The list goes on and on, really.

RTOS for concurrency

With physical computing, it’s not uncommon to have to deal with many different tasks at (nearly) the same time: LEDs blinking, buttons getting pressed, data coming in and going out, high-speed ADC acquisition, wired and wireless communication, responding to critical conditions – depending on the project, there can be a lot of things going on.

That poor instruction-by-instruction µC may have a hard time keeping up. Or rather: us, trying to program all the logic and making sure all the combinations work as intended!

This is where the RTOS comes in: it’s like a mini operating system, aimed at switching the CPU around to perform multiple tasks. Which is in fact only half the problem: with multiple tasks there comes the need for robust ways to make these tasks work together – semaphores, mutex’es, critical regions, interrupt hierarchies. A slew of (tricky!) techniques.

MBED has an RTOS available as part of its runtime library (and a new one in progress).

ChibiOS is another example, with a “Hardware Abstraction Layer” (HAL) as well as all the fore-mentioned inter-task communications and synchronisations primitive. An interesting development is Nil, which shares a lot of code with ChibiOS, but aims for a very low code overhead by leaving out some of the more advanced and dynamic features.

The most widespread OSS RTOS is probably FreeRTOS. It’s mature and extensive.

One benefit of the RTOS is that it also creates a lot of conventions and an API, not just for the tasking side of things but also for the way devices are integrated into the application. This in turns encourages writers of larger libraries to tie into them, such as for accessing and modifying (µ)SD cards as a (V)FAT file system and for a full Ethernet TCP/IP stack.

Such more extensive features do need more flash and RAM memory, though. It’ll be hard to fit many features into a low-end ARM chip, alongside the RTOS itself (usually 2..10 KB).

Note how a complete RTOS with several advanced libraries really does start to make an embedded µC like a “big” computer! Megabytes of flash and RAM, gigabytes of permanent storage – it’s all feasible with larger µCs when combined with some external memory chips. Here is an example, with 8 MB flash, 32 MB RAM, and Ethernet, on a 28 x 104 mm board.

But the common theme with all of the above is really: cross-compilation (mostly C/C++) with uploading of the build result. The µC as a full-blown programmable computer, with the major tasks of editing, compiling, linking, and even debugging off-loaded to a “host”.

[Back to article index]