Learn how to program embedded systems in 10 easy steps!

At TTE Systems, we receive many enquiries from people who want to learn how to program embedded systems. The questions come from professional programmers (particularly those who are considering a career change from “desktop” to “embedded” systems) as well as from students and hobbyists.

In many cases, the people concerned have limited funds available.

In response to these questions, we’ve created this webpage. On this page, we provide a “10-step guide” for people who want to learn how to program embedded systems. Our focus is on ways in which people can learn how to create reliable systems.

1. Learn how to program in C for a “desktop” computer

Before you can start to program embedded systems, you need to learn how to program. While it is not impossible to begin programming using an embedded board, most people find it much easier to learn how to program on a desktop computer before they start to deal with the complexities of cross-compilation, debugging over a JTAG link, etc.

We therefore recommend that you learn how to program a desktop computer, in C, before you start trying to program an embedded processor.

To explain why we recommend learning C, we make the following observations:

  • Computers (such as microcontroller, microprocessor or DSP chips) only accept instructions in “machine code” (“object code”).
  • Machine code is, by definition, in the language of the computer, rather than that of the programmer. Interpretation of the code by the programmer is difficult and error prone.
  • All software, whether in assembly, C, C++, Java or Ada must ultimately be translated into machine code in order to be executed by the computer.
  • There is no point in creating ‘perfect’ source code, if we then make use of a poor translator program (such as an assembler or compiler) and thereby generate executable code that does not operate as we intended.
  • When compared to “desktop” processors, embedded processors tend to have limited processor power and very limited memory available: the language used must be efficient.
  • To program embedded systems, we need low-level access to the hardware: this means, at least, being able to read from and write to particular memory locations (using ‘pointers’ or an equivalent mechanism).

Of course, not all of the issues involved in language selection are purely technical:

  • No software company remains in business for very long if it generates new code, from scratch, for every project. The language used must support the creation of flexible libraries, making it easy to re-use (well-tested) code components in a range of projects. It must also be possible to adapt complete code systems to work with a new or updated processor with minimal difficulty.
  • Staff members change and existing personnel have limited memory spans. At the same time, systems evolve and processors are updated. Many embedded systems have a long lifespan. During this time, their code will often have to be maintained. Good code must therefore be easy to understand now, and in five years time (and not just by those who first wrote it).
  • The language chosen should be in common use. This will ensure that you can continue to recruit experienced developers who have knowledge of the language. It will also mean that your existing developers will have access to sources of information (such as books, training courses, WWW sites) which give examples of good design and programming practice.

Even this short list immediately raises the paradox of programming language selection. From one point of view, only machine code is safe, since every other language involves a translator, and any code you create is only as safe as the code written by the manufacturers of the translator. On the other hand, real code needs to be maintained and re-used in new projects, possibly on different hardware: few people would argue that machine code is easy to understand, debug or to port.

Inevitably, therefore, we need to make compromises; there is no perfect solution. All we can really say is that we require a language that is efficient, high-level, gives low-level access to hardware, and is well defined. In addition - of course - the language must be available for the platforms we wish to use. Against all of these points, C scores well.

We can summarise C’s features as follows:

  • It is a ‘mid-level’ language, with ‘high-level’ features (such as support for functions and modules), and ‘low-level’ features (such as good access to hardware via pointers);
  • It is very efficient;
  • It is popular and well understood;
  • Even desktop developers who have used only Java or C++ can soon understand C syntax;
  • Good, well-proven compilers are available for every embedded processor (8-bit to 32-bit or more);
  • Experienced staff are available;
  • Books, training courses, code samples and WWW sites discussing the use of the language are all widely available.

Overall, C’s strengths for embedded system development greatly outweigh its weakness. It may not be an ideal language for developing embedded systems, but is unlikely that a perfect language will ever be created.

2. Learn the basics of “embedded C”

When you are familiar with desktop C, we suggest that you begin to explore embedded systems using a simple processor. For example, the 8051 microcontroller is a popular “starter” processor which is still used in many “real” systems.

If you decide to start with the 8051 microcontroller, “Embedded C” provides a gentle introduction to the programming of embedded systems (using 8051 microcontrollers). Please note that Embedded C is a self-contained “teach yourself” program: the package includes both a compiler and processor simulator (on CD), which means that you can run all of the examples in the book (and learn a great deal about the programming of embedded systems in C) without buying — or building — any hardware.

Please note that two Chinese translations of “EC” are available (one for Taiwan, one for mainland China).

Cover of Embedded C

  • Pont, M.J. (2002) “Embedded C”, Addison-Wesley. ISBN: 0-201-79523-X.
  • Pont, M.J. (2003) “Embedded C”, Chinese Electric Power Press. ISBN: 7-5083-1814-5.
  • Pont, M.J. (2004) “Embedded C”, Pearson Education Taiwan. ISBN: 986-7491-52-1.

If you can’t afford to buy a textbook at this time, a set of lecture notes are available which provide an introduction to the programming of embedded systems with C are available from the University of Leicester (please scroll to the bottom of the page and follow the links to “lecture handouts”).

3. Buy a low-cost evaluation board and programming / debug cable

When you have learned the basics of “Embedded C”, you are ready to buy (or borrow) an evaluation board with an appropriate chip. At this stage, we recommend that you consider a board with an ARM-based microcontroller.

We suggest that you don’t buy an evaluation board unless it has at least one LED connected to a port pin. Ideally the board should have at least one push-button switch too.

We suggest that you also ensure that the board can be programmed easily and cheaply (ideally by means of a JTAG interface, which will allow you to work with breakpoints, etc, as you start debugging).

As a flexible and cost-effective evaluation platform, we suggest you consider the LPC-P2129 board from Olimex Ltd, along with an Olimex USB-based (JTAG) debugger.

For example, a complete set of this hardware is available from SK Pang Electronics. This starter kit includes an Olimex LPC-P2129 board plus Olimex USB-based (JTAG) debugger hardware and all necessary cables.

An LPC-2129 evaluation board with JTAG debugging hardware

In the Netherlands, you can buy Olimex LPC2129 boards and JTAG debuggers from Van Ooijen Technische Informatica.

In the US, you can buy Olimex LPC2129 boards from MicroController Pros Corporation, or from SparkFun Electronics.

Also in the US, you can buy Olimex JTAG debuggers from SparkFun Electronics.

4. Buy or download a C compiler that matches the above board

For your first set of development tools, may we suggest that you consider RapidiTTy™ Lite?

RapidiTTy™ Lite is a simple but complete development tool based on the industry-standard Eclipse IDE and incorporating a GCC ARM compiler. The compiler supports a wide range of ARM-based processors.

RapidiTTy™ Lite is available for free download (no registration is required).

A key feature of RapidiTTy™ Lite is that the package includes a number of complete example programs that target the popular NXP LPC2000 family of microcontrollers.

The wide range of examples include a simple “real-time operating system” (sEOS), plus use of I/O facilities including switches, LCDs (in an “intruder alarm” system), analogue-to-digital conversion (ADCs), pulse-width modulation (PWM: including speech playback), etc.

In many cases, the examples can be used with the cost-effective LPC-P2129 development board from Olimex Ltd: they can be adapted for use with other boards (and other processors) without difficulty.

5. Learn how to flash an LED

Your next step is to find a simple C program (ideally one which matches your board and compiler precisely) which will flash the LED on your board. You need to compile and link this program and download it to the board.

As you would expect, RapidiTTy™ Lite includes a number of suitable example programs.

You may also wish to refer to the manuals for the NXP LPC2129 processor as you work on this example (but we suggest that you don’t try to read everything at this stage).

6. Experiment with the flashing LED code

When you have the LED flashing, congratulate yourself (you’ve come a long way already).

Now it’s time to experiment. Add some breakpoints. Change the rate at which the LED flashes. Flash a different LED.

7. Add a switch interface

Add a switch interface (when you press the switch, the LED flashes, etc).

A switch example is included in the RD-RES book project.

8. Add an RS-232 interface

Try to write a program which will control the serial (RS-232) interface.

Use of the RS-232 interface is explained in in the RD-RES book project.

9. Read RD-RES

The “Rapid Development of Reliable Embedded Systems” book project begins by covering similar ground to “EC” and “PTTES”, with a focus on the use of microcontrollers with ARM cores (ARM7, ARM9, Cortex M3).

These book chapters are available for free download.

10. Learn more about FPGAs

Developers of modern embedded systems have two main implementation options. First they can choose to employ a “commercial off-the-shelf” (or COTS) processor. Second, they can choose to implement their design using a “field-programmable gate array” (FPGA), using what is known as a “soft core” processor.

As the cost of FPGAs continues to fall (and power consumption figures improve), the opportunity to implement embedded systems using soft-core processors and FPGAs is becoming of increasing interest. For developers who wish to explore the use of FPGAs in embedded designs, RapidiTTy™ FPGA Lite provides an excellent starting point.

RapidiTTy™ FPGA Lite is available for free download (no registration required).

RapidiTTy™ FPGA Lite is bundled with a “soft core” for the PH processor. The instruction set of this processor core is compatible with the MIPS I architecture, including all of the non-patented integer operations.