Black Box with a Viewby George Belotsky
What is an embedded system? With embedded Linux (and Windows) getting plenty of press coverage, it appears that the embedded environment is much like an ordinary PC. In fact, most embedded systems do not run Linux or Windows. Instead, the microcontroller dominates the field. These single-chip devices resemble an Apple II or a Commodore 64--the personal computers of 25 years ago.
Figure 1. Pin-side views of an Intel 486 DX CPU (left) and a Texas Instruments MSP430F149 microcontroller
Consider Figure 1. The 486 is the sort of device that could run Linux in an embedded environment, while the MSP430 is a typical modern microcontroller. In particular, note the far smaller number of pins on the MSP430--a rough indication of the relative complexity of the two devices.
Like early personal computers, traditional microcontroller applications are tiny islands of functionality, with little connectivity to the outside world. Consider such devices as a microwave oven, a telephone answering machine, and a wristwatch. Each system has its own user interface, and each performs its own highly specialized task.
It is not possible, for example, to turn off your microwave oven remotely with the wristwatch by using the answering machine as a telephone communications gateway. With the emergence of initiatives such as the Cambridge-MIT Institute's Pervasive Computing, however, such capabilities could become common.
The goal of Pervasive Computing is to create a network of collaborating machines, possibly with hundreds of devices per user. These collaborating groups of connected embedded systems will likely be the next mainstream computing platform. The ordinary PC will then follow its mainframe predecessor to become a specialized tool (albeit still an important one) for a relatively small set of core applications.
While the age of Pervasive Computing has not yet arrived, much of the necessary technology is available today. Powerful microcontrollers (some of which feature very low power consumption) are widespread. You can even purchase inexpensive development kits with Ethernet hardware already onboard.
An embedded system designed for connectivity is like a precisely defined window put on the traditional black box device. Sophisticated diagnostics, advanced interaction with the user, and meaningful network simulations (supported by actual hardware) all become possible.
The purpose of this series of articles (continued in Black Box with a View, part two) is to help you develop connected embedded systems using current technology. Communication between the embedded device and a standard PC is particularly useful, due to the current prevalence of as well as significant computing power of the latter. In the Pervasive Computing future, interaction with PC-type hardware will also continue to be important, because such systems will play the role of gateways and control workstations for networks of embedded devices.
The Nature of Embedded Systems
It is important to understand the nature of embedded systems before starting your own project. If you have little experience with such systems, this article will provide a foundation. The next article will build on the information presented here, by covering several key embedded development techniques. Advanced readers can use these two articles as a review.
Embedded software is the focus of discussion here, so this article covers everything you need to start quickly. You will not have to build any hardware in order to follow the examples in this series of articles. Of course, you will need at least some knowledge of electronics and a basic set of tools (a digital multimeter, a soldering iron, and so on) in order to complete an actual project.
In the microcontroller world, assembly language and C still dominate. C++ is also popular but is not as well supported as C. This series therefore uses the C language for the examples. The resulting code is quite easy to read, although you should have at least some prior knowledge of the language. You should also have a good C reference book (such as C: A Reference Manual) that covers the complex details of the language and its implementations. The reference book is not necessary to follow these articles, but it will be helpful for your own projects.
In addition, keep in mind that operating system support is minimal in microcontroller-based devices. Any serious work requires direct interaction with the hardware. In fact, embedded software often runs with no operating system at all--as the examples in this series illustrate. If you have experience with programming under Linux or Windows, embedded development is much more like writing a device driver than a typical application program in those environments.
Despite their many similarities to early personal computers, microcontrollers are not designed for general-purpose computing as we know it today. In particular, the balance of storage capacity and processing power is very different in embedded applications. For example, the Texas Instruments (TI) MSP430 microcontroller (PDF file) shown in Figure 1 can run at 8MHz but has a maximum of 2K of RAM and 60K of flash memory for storing code as well as static data. Models with 10K or 5K of RAM are available, but only with smaller amounts of flash memory. One MSP430 variant has just 128 bytes of RAM and 1K of flash. In contrast, the Commodore 64 ran at 1MHz but had 64K of RAM, 20K of ROM, and several secondary storage options--including a floppy disk drive with 170K per disk.
Of course, secondary storage solutions (such as flash memory devices) are also available for embedded systems. Unfortunately, the constraints of cost, power consumption, and physical size are often very stringent in embedded applications. In addition, many devices need to survive shock, vibration, and other extreme environmental conditions. Thus, the multigigabyte hard disk, so common in the PC world, is rarely suitable for embedded projects. As the result, microcontroller software design often emphasizes efficient memory use over processing speed--the exact opposite of general PC-based development.
Choosing a Platform
The modern PC landscape consists of relatively few variations in system architecture. In contrast, there are significant differences between many microcontrollers. Traditionally, these were 8-bit devices, but 16-bit and even some 32-bit components are now common. The diversity of embedded applications, combined with often severe application-specific limits, require a corresponding diversity in the choice of microcontrollers.
For this series of articles, several key considerations drove the platform selection:
- the availability of good open source development tools
- the ability to host the tools under both Windows and Linux
- the availability of inexpensive, fully featured development kits
- a microcontroller architecture that facilitates efficient compiler-generated code
- sufficient capabilities to make development relatively easy
- not so much capability that the "feel" of embedded development is lost
The TI MSP430 microcontroller matches these criteria very well. Of course, many alternatives are possible (the Atmel AVR and the ARM7, for example). If your budget allows, order several development boards based on different microcontrollers so that you can experiment before making the final choice for a project.
The MSP430 is an 8MHz, 16-bit device with a RISC core and an orthogonal instruction set. These features allow very efficient object code generation by a compiler. Assembly language programming--often required on less compiler-friendly architectures--is used far less frequently on the MSP430. Nevertheless, the MSP430 still is very much a microcontroller. The techniques presented in this series of articles would not be out of place on an Intel 8051, designed in the 1980s and still very popular.
Several proprietary C compilers are available for the MSP430. These articles, however, use the open source mspgcc. Mspgcc is a port of the famous GNU Compiler Collection (GCC) compiler suite to the MSP430. Appendix A gives directions for installing mspgcc under both Windows and Linux.
Mspgcc provides a complete set of open source tools, including support for symbolic debugging. Note, however, that debuggers are often harmful in the embedded environment. The next article will discuss the subtle problems that symbolic debuggers can introduce.
The development board used for these articles is the Olimex easyWeb2. Compiled programs are loaded onto the board via the Olimex JTAG adapter. Olimex ships internationally. The author purchased the easyWeb2 and the JTAG adapter through the Olimex North American Distributor, Spark Fun Electronics.
You will also need a DC power supply to run the easyWeb2. The familiar AC adapter ("power brick") fulfills this need simply and inexpensively. Spark Fun will sell you a suitable adapter for a small additional cost.
Note that the easyWeb2 regulates its power input (see the schematic), so do not be surprised if different distributors offer adapters with different ratings. This also means that you may already have an adapter that will work with the easyWeb2. If in doubt, however, it is much safer to purchase the right power supply when you buy your board.
See Appendix B for information on how to set up the hardware.
Figure 2. The easyWeb2 development board
In Figure 2, note the JTAG adapter ribbon cable at the top left. The red stripe on the cable designates pin 1. Make sure that you match the stripe to the actual pin 1 of the JTAG connector. A label on the board beside this connector designates pin 1. The plug for the AC adapter is also visible near the top right corner of the board.
The easyWeb2 includes input switches, relay-driven outputs, a small LCD screen, and an RS232 serial port. There's also an Ethernet port (along with the required supporting hardware) for developing embedded network devices that can attach directly to the LAN.
Support for serial communication is particularly important for the later articles in this series. RS232 and RS485 I/O is simple, but surprisingly capable. It remains the prevalent method for embedded system connectivity today.
Of course, many other MSP430-based boards are available. You can even build one yourself (perhaps using a development kit as a starting point). If you want to use something other than the easyWeb2, the following requirements should be sufficient:
- A flash-programmable MSP430 with mspgcc support (see the "Compiler options" subsection in the mspgcc manual) and at least one USART device. The USART is necessary to implement the serial I/O examples in this series of articles. The easyWeb2 uses an MSP430F149, which provides the required USART, as well as 2K of RAM and 60K of flash memory--quite generous by embedded standards.
- A standard 9-pin RS232 serial port, connected to the microcontroller's USART. Note that this requires shifting voltage levels in order to implement correctly. The port uses only three wires (receive, transmit, and ground) to communicate.
- At least one LED, connected to a digital I/O pin on the microcontroller. The examples assume that this is pin 1 on port 2; you will need to make minor changes to the code if your configuration is different.
- The ability to program the device via JTAG or the MSP430 serial bootloader. The easyWeb2 supports JTAG.
The examples in this series use JTAG to upload the firmware to the target. If your hardware supports the serial bootloader, using it is quite similar to using JTAG. The serial bootloader is slower and does not allow symbolic debugging, but it is more reliable. The mspgcc project includes tools (pyJTAG and pyBSL) for both methods.