12 January 2016

Motivation

There are many, many, many commercial options for embedded systems development. Even if you restrict yourself to one company’s line of chips, ST's STM32 line, say, you will find many choices of compiler, IDE, supporting tools, firmware, and other such things in the commercial world.

Tip This is not what this series is about.

There are many arguments in favour of commercial software development. There are many arguments about free/open-source software (F/OSS). There are many arguments between proponents of free software and "mere" open-source software. All of these arguments can and do lead to heated, unproductive debates on each approach’s respective merits.

Tip This is emphatically not what this series is about!

What this series is about is helping someone who has already decided that they wish to use F/OSS to do embedded systems, or who is interested in the possibility and wishes to explore it, get up to speed and ready to create embedded software for embedded systems.

So what’s the advantage that may make someone interested in it? Ignoring all the (often politically-flavoured) arguments, there is only one that matters to most people: it’s cheaper (which is especially good for hobbyists!) and it can often be surprisingly higher quality software on top of that.

Reader expectations

This series of articles is aimed at a competent C programmer. You don’t have to be a C wizard/rockstar/ninja/whatever-the-pretentious-call-themselves-this-week, but you have to be comfortable with the C language to the point that you can read well-written code with little "decoding" required.

You will need decent debugging skills. This doesn’t mean "knowing the debugger commands". This means knowing the techniques of debugging including instrumentation, bifurcation, and just plain reasoning about the code. If you’re not comfortable with your debugging skills, perhaps brushing up on those a bit will make you more comfortable as the series progresses.

A final thing you’ll need is a willingness to do hands-on work. Initially the series will not involve a lot of wiring. Indeed you’ll just be plugging a USB cable into a device and your computer. As we go on, however, you’ll be connecting a variety of devices together using everything ranging from Dupont connectors to breadboards to …​ <gasp!> …​ maybe even soldering! (There won’t be much of that last one, however, because I hate it too.)

Tooling

There are several components you need to get together for embedded systems programming. Some of these are essential (hardware, development platform, compiler suite, debug server), some are useful to the point of it being mad not to have them (drivers and libraries), some are very nice to have when making complex systems (RTOS) and some are frills that a certain kind of developer can’t seem to live without (IDE). The purpose of this prelude article is to list these tools for you and then provide guidance on how to set them up.

So first, the components:

Hardware

There is a need for some kind of development board with a target microcontroller unit (MCU: effectively a CPU with some I/O peripherals) and, optionally, some peripheral devices to exercise. You can’t do embedded development without anything to embed, after all. In addition to this, you need something to sit between your computer and the target MCU to interpret the debugging command system (usually JTAG or SWD these days) into something your debugger and/or IDE can cope with.

Development platform

You need a host system of some kind to write your code on, compile it, and run debugging tools, source control systems, etc. under. Most commercial systems run on Windows, a non-F/OSS operating system. In the spirit of F/OSS, however, it would be interesting to show a fully F/OSS approach.

Compiler suite

You can’t use MSVC or any platform-native compiler to write embedded software. Odds are that your development platform is running on an x86 core of some kind. The compilers that you use for that environment will not work on almost all embedded systems. (Very few embedded systems use x86 cores!) For this reason you need to have a "cross-compiler" that generates code for your "target system", which is to say the machine the code will actually run on.

Debug server

There are a myriad of hardware debugging interfaces in (ab)use (JTAG, SWD, SPI, I2C, etc.) which is further compounded by having different transports for connecting to them (USB, Ethernet, RS-485, etc.). Further every core has its own debug module ranging from "none whatsoever" to "complex hardware command language". It is not possible for general purpose debuggers to attach to them all (although some try). The better and more common solution is to have a layer of software—the debug server—that sits between the debugger and the hardware to translate from the hardware-specific "language" to the debugger’s. (These are often used to load the software onto the chip as well.)

Drivers and libraries

In theory it is possible to program straight to the hardware. Most manufacturers provide massive tomes of information on how to do just that. Almost nobody uses that information directly, however, choosing instead to use any number of drivers and libraries supplied by the manufacturers or third parties instead.

RTOS

Standing for "Real-Time Operating System", an RTOS is usually a simple executive designed for making complex real-time systems. On small projects (the kind that have 2KB of RAM or less) these can add an unacceptable overhead, but on larger projects—projects which usually have commensurately more complicated software—they can be a boon.

IDE

The world of F/OSS IDEs is typically pretty dire. Embedded software is no exception. That being said, for those who simply cannot live with the command line there are choices available.

Hardware

The board I’ve selected for this series is the STM32F3DISCOVERY. This board was selected for several reasons.

  1. It’s a cheap board, averaging about US$10 to purchase. This means that if you decide that embedded software is not for you, you’re out a minimal amount of money.

  2. It has a good MCU at its core (STM32F303VCT6) that has a good blend of modern features, including:

    • 32-bit ARM Cortex-M4 core;

    • 72MHz maximum clock;

    • a floating point unit;

    • a memory protection unit;

    • 256KB of persistent storage (Flash);

    • 48KB of dynamic storage (SRAM);

    • loads of interesting and useful capabilities including DSP functionality, analogue capabilities, loads of GPIO, a variety of timers in a variety of timer modes, DMA, op-amps, communication interfaces, etc.

  3. It has a built-in debugging interface (ST-Link/V2) so you don’t have to worry about buying an extra piece of hardware, wiring things up, wrestling with configurations, etc. Further, the board can be converted by removing two jumpers into an ST-Link adapter for other boards for when you decide to expand into the broader world of embedded systems programming.

  4. The board is not overwhelming. Besides the MCU’s built-in peripherals it adds a small number of extras that are easy to learn:

    • a 3-axis gyroscope;

    • a combined 3-axis accelerometer and 3-axis magnetometer;

    • a user USB port;

    • a user button;

    • eight LEDs in various colours in an eye-catching circular arrangement.

  5. The board is also not distracting. There are other evaluation boards available (even in ST’s Discovery line) that have touch screens and other razzle-dazzle capabilities. These distract, however, from actual embedded programming by mimicking being full-fledged computers in their own right. The STM32F3DISCOVERY is very clearly an embedded system.

  6. Most of the MCU’s useful pins are exposed for further expansion. You’ll be able to extend this board with a display, or an SD card storage system or any other such device with ease as you grow.

  7. I’m somewhat of an ST fanboi and I will use what I’m familiar and happy with as a result.

Note Since this is my blog, my rules, the last item is all that really matters to me, but the other reasons are still valid.

Acquiring the STM32F3DISCOVERY

  • Visit the home site for the board.

  • Click on "Sample & Buy" in the second layer menu.

  • Several possible sources for the boards are listed. Choose one and order.

Alternatively a quick DuckDuckGo search can find several more sources with a bit of picking around. AliExpress is also a viable search option.

Acquiring the STM32F3DISCOVERY documentation

While you’re waiting for your hardware to arrive, you may want to download some of its documentation. There is a lot of documentation available for it and for the MCU it holds. Fortunately most of it is reference documentation you only use when actively using the portions you’re aiming for. You don’t have to download them all. To get the documentation:

  • Visit the home site for the board.

  • Click on "Design Resources".

  • Download the following documents:

    • DB1739 (data brief)

    • AN4157 (firmware examples)

    • UM1562 (getting started)

    • UM1570 (board documentation)

  • If you have a flair for digital electronics, downloading the schematics and BOM may be of interest. This is not necessary, however, and if you don’t know what it means you probably don’t need it just yet.

  • Now visit the STM32F303VCT6 page and click on "Design Resources" again.

  • Download the following documents:

    • DS9118 (data sheet)

    • RM0316 (reference manual)

    • PM0214 (programming manual for the Cortex-M4 core)

Tip YOU WILL NOT HAVE TO READ ALL THESE DOCUMENTS! They are available for reference when you wish to understand something deeper than the API level or, sometimes, for debugging things down in the guts of the MCU. Scanning over them to be aware of the kind of information each has is enough.

Development platform

While it’s possible to use everything in this article from Windows, it kind of violates the spirit of free software to use a commercial OS for liberating embedded software! There are two main branches of F/OSS operating systems in use: Linux and BSD, but Linux distributions' use outweighs the BSDs by far. For purposes, then, of this series, I will assume some form of Linux system. If you choose to use Windows (or OSX!), or if you choose to go with a BSD, you will obviously have to make adjustments to some of these procedures. I will not be able to advise you on these adjustments, however, as I do not use these OSes.

The specific version of Linux I’ll be using for this series is Linux Mint. You can choose any version of it (there are several desktop flavours available).

If you are not comfortable moving away from Windows, the good news is that you don’t have to. VirtualBox will let you run Linux as a task inside your Windows environment! It adds a small amount of extra setup complexity (specifically on making your STM32F3DISCOVERY board automatically captured by the Linux ecosystem) but after that it’s just a matter of launching Linux as a program under Windows and using it from there.

Acquiring and installing the development platform

  • Visit the Linux Mint home site and download the version with the desktop you’d most like. If you want something close to being Windows-like in look in feel you’ll want the MATE or Xfce editions. Of the two Xfce is the simplest and the one that uses the fewest resources.

  • Download the ISO file for the version you want.

  • Visit VirtualBox and download it and its Extension Pack (this is very important!).

  • Install VirtualBox according to the supplied instructions.

  • Install the Extension Pack according to the supplied instructions.

  • Create a virtual machine (VM) inside of VirtualBox and point it to the ISO file you downloaded for its CD drive.

  • Install Linux Mint into the VM.

  • Plug in your STM32F3DISCOVERY card.

  • In the USB settings for your Linux VM configure it such that your VM automatically captures the ST-Link/V2 device.

Now, any time you want to do Linux-based development, just fire up VirtualBox and start your Linux VM. Plug in your STM32F3DISCOVERY board and everything should be ready to use.

Going raw Linux

If you’re brave, or if you have a machine to spare, you can always just install Linux directly onto your machine without VirtualBox in the loop. If you choose this path, only follow the first two instructions above, and after downloading the ISO file, burn it to DVD and boot from it to install Linux Mint.

Other Linux distributions

There are a large number of Linux distributions. Linux Mint is considered one of the gentler introductions. If you choose to use another distribution, however, this is also valid. You may have to alter some of the instructions I provide to suit your distribution’s way of doing things. Linux Mint, for example, uses the APT family of package management tools (as do many others). If you choose to use a Red Hat-derived distribution, however, you will use YUM or DCF. If you use an Arch-derived distribution, you will use Pacman. In such cases you will have to consult the relevant documentation to accomplish the same ends.

Compiler suite

As far as I’m concerned there is only one good package available for doing F/OSS embedded programming: GCC ARM Embedded (a.k.a. arm-none-eabi). This is an ARM project for providing a high-quality F/OSS compiler for ARM Cortex-M and Cortex-R processor cores. It is actively developed and constantly improved.

Acquiring and installing arm-none-eabi

Tip If you’re going to use an IDE, this step is not required.

Visit GCC ARM Embedded's home page and follow the instructions. If you’re using an APT-based package manager (like Linux Mint!) it would be best to use the GCC ARM Embedded PPA to install the suite by just following the instructions on that page. If you’re using another Linux distribution that doesn’t use APT, you’ll either have to install from the generic binary provided in the downloads section or you’ll have to build it from scratch yourself.

Warning This latter course of building it yourself is not recommended!

Debug server

The best of breed in the F/OSS debug server world is the Open On-Chip Debugger (OpenOCD). It supports a huge number of chips and boards, is under constant, active development by responsive, helpful volunteers, and works like a champ.

Acquiring and installing OpenOCD

Tip If you’re going to use an IDE, this step is not required.

There is good news and there is bad news on this front. First the good news: OpenOCD is in the Linux Mint repositories! Now the bad: it is a version that is horribly out of date. You will have to build your own.

Building your own is easy enough, for the most part, from your Linux VM:

  • Visit the project’s files page and select the most recent version (0.9.0 as of this writing).

  • Download openocd-<version>-tar.gz.

  • Execute tar xvf openocd-<version>-tar.gz

  • Switch into the newly-made openocd-<version> directory.

  • Now issue the command more README and read the instructions carefully!

  • Now issue the command more INSTALL and read the instructions carefully!

  • Follow the provided instructions. In particular make note of the libraries you will have to first install to build OpenOCD.

The lazy way out

It is possible to go to Getting OpenOCD and to download a prebuilt binary. I do not recommend this, but if, again, you must, choose the most recent stable version, not the development version!

Drivers and libraries

There are a huge number of firmware libraries, both commercial and free, available for running on STM32 cores. For the sake of simplicity, however, this series will focus on using ST's own embedded software for its STM32F3 family: STM32CubeF3, a library of drivers and middleware that you can use to more quickly build running software on your STM32F3DISCOVERY.

Caution STM32Cube is a large, and confusingly-named, suite of software tools that includes firmware for all of its chip lines and a code generator that integrates all of that. We will not be using the code generator portion—STM32CubeMX—of their software, however, because getting it to work in a F/OSS environment with a F/OSS IDE is not trivial.

STM32CubeF3 contains within it:

  • a set of HAL low-level drivers for the chips' baked-in peripherals;

  • USB support;

  • FAT file system support;

  • an RTOS (c.f. below);

  • touch sensing and graphics routines;

  • examples for various STM32 boards and kits.

It is not perfect software by any means (what is?), but it is good enough for getting familiar with the ecosystem.

Important Not everything in STM32CubeF3 is open sourced! Some are third-party utilities licensed by ST, for example, that have been delivered only in binary format. Don’t use these if you wish to remain fully F/OSS.

Acquiring and installing STM32CubeF3

This is a simple download and unzip:

  • Visit the STM32CubeF3 page.

  • Click on "Get Software".

  • Click on "Download".

  • While you’re waiting, click on "Design Resources".

  • Download at a minimum the following documents as well:

    • DB2348 (data brief)

    • AN4734 (firmware examples)

    • UM1721 (FAT file system notes)

    • UM1722 (FreeRTOS notes)

    • UM1734 (USB notes)

    • UM1766 (getting started)

    • UM1786 (HAL reference manual)

    • UM1913 (touch sensing notes)

  • When the ZIP file arrives, find a place for it and unzip it.

  • Copy the downloaded documentation files into the Documentation subdirectory.

As with the hardware documentation, you will want to at least glance over these documents to become familiar with what kind of information each contains. You will be referring back to them frequently while making your software. On the other hand you will not be reading these from cover to cover. Most of them are either reference documentation or task-specific documentation for specific peripherals and/or middleware.

RTOS

As with driver libraries, there are dozens of real-time operating systems available for ARM Cortex-M cores. As, too, with driver libraries I’ve decided to go the easy route and take the RTOS that comes with STM32CubeF3: FreeRTOS. It’s a popular option and, again, it is the path of least resistance for starting off with embedded in F/OSS.

Acquiring and installing FreeRTOS

This is already done. FreeRTOS is included in STM32CubeF3 (and has been properly ported to that specific chip already for you).

IDE

If you choose to use an IDE, the System Workbench for STM32 will be the IDE used in examples in this series. It is an IDE focused specifically on ST's STM32 line of chips that is based on the popular and very familiar Eclipse framework for IDEs. Users who already know and use Eclipse will find nothing surprising here at all. Users of other IDEs will find most of Eclipse understandable without a lot of work.

Note As a personal note, I should make it clear that using the IDE will be a second-class element in this series. The reason is clear: I don’t use IDEs. There are many advantages to using IDEs, of course, and there are disadvantages.
Table 1. The IDE choice
Advantages Disadvantages

Unified access to components

Component choice is forced

Simpler installation and component management

Harder to exchange or replace tools

Looks nicer

Not flexible in available extra tooling

Familiar feel for most developers

Individual tools often not as powerful as external tools

Usually well-integrated with SCM

For my purposes I choose to typically not work with an IDE. I understand, however, that this is not a preference shared by all (or even most) developers. I will thus be trying to at least offer some guidance in how to use an IDE to do embedded software with F/OSS tools.

Note Another possible F/OSS IDE for embedded development is CooCox’s CoIDE, but as with previous choices above if you go this route you will be doing some of the legwork yourself.

Acquiring and installing System Workbench for STM32

  • Go to the IDE’s home page.

  • Register at the site.

    • For those unwilling to give out personal e-mail for this, an understandable desire, Mailinator is a good source of temporary email accounts for throw-away registrations and their ilk.

  • Follow the link to "Installing System Workbench for STM32 with installer".

  • Scroll down to "Installing on Linux" and read the instructions.

  • Skim over the user guide to get familiar with the environment.

Other things

You will need a text editor at the very least if you didn’t go the IDE route. I am not going to get into this war. Pick whatever text editor you like best. My personal choice, for example, is Textadept. I am not going to tell you to get it, however, nor will I defend it if you try it and decide you don’t like it. Other popular options include Sublime Text, jEdit, Kate, GEdit, Vim, Emacs, SciTe, and a host of others.

The two most common code editors in Unix-like space are Vim and Emacs. You can find lots of information on both of these editors online. Sadly you can also find a lot of geeks with no sense of proportion arguing about which is better. Ultimately you’ll have to make your own choice based on your own needs and tastes.

You will also need some form of source control. Since I’m assuming you’re already a programmer, I assume that you already have a source control system that you know and love. I do too, but it’s probably not the one you use.

There are many options for revision control on Unix-like spaces: Git, Fossil, Mercurial, Bzr, Monotone, Subversion, even CVS. And a few more. Pick one you know or can easily grow to know and use it. I will not be addressing SCM any further.

Conclusion

This is the beginning of a series of articles on using F/OSS tooling to do embedded software development. If you’ve followed all the steps above you should have enough to start building embedded software under Linux using only free or open source tools.

Future installments of this series will build up on these tools you’ve installed to allow you to start creating the stuff you want in the embedded world, staying free and easy all the while.