Developing Embedded Systems - A Tools Introduction
by Volker Soffel
Developing software and hardware for microcontroller based systems involves the use of a range of tools that can include editors, assemblers, compilers, debuggers, simulators, emulators and Flash/OTP programmers. To the newcomer to microcontroller development it is often not clear how all of these different components play together in the development cycle and what differences there are for example between starter kits, emulators and simulators.
To complicate matters more, there are quite a number of different approaches and technologies for emulation available that make it difficult for even seasoned embedded engineers to pick the right tools. With this article, I'll try to give a short explanation of the different tools involved in the microcontroller development cycle, with a particular focus on the different emulator types and their advantages and disadvantages.
So let's start out by looking at the typical microcontroller software development cycle with some of the software and hardware components involved:
Above picture shows the typical microcontrollers firmware development cycle, which involves:
Software Code for a microcontroller is written in a programming language of choice (often Assembler or C). This source code is written with a standard ASCII text editor and saved as an ASCII text file. Programming in assembler involves learning a microcontroller's specific instruction set (assembler mnemonics), but results in the most compact and fastest code. A higher level language like C is for the most part independent of a microcontroller's specific architecture, but still requires some controller specific extensions of the standard language to be able to control all of a chip's peripherals and functionality. The penalty for more portable code and faster program development is a larger code size (20%...40% compared to assembler).
Next the source code needs to be translated into instructions the microcontroller can actually execute. A microcontrollers instruction set is represented by "op codes". Op codes are a unique sequence of bits ("0" and "1") that are decoded by the controller's instruction decode logic and then executed. Instead of writing opcodes in bits, they are commonly represented as hexadecimal numbers, whereby one hex number represents 4 bits within a byte, so it takes two hex numbers to represent 8 bits or 1 byte. For that reason a microcontroller's firmware in machine readable form is also called Hex-Code and the file that stores that code Hex-File.
Assemblers, Compilers, Linkers and Librarians
Assemblers or (C-) Compilers translate the human readable source code into "hex code" that represents the machine instructions (op codes). To support modular code and reusable libraries of code, most assemblers and compilers today come with Linkers and Librarians.
Linkers, link code modules saved in different files together into a single final program. At the same time they take care of a chip's memory allocation by assigning each instruction to a microcontroller memory addresses in such a way that different modules do not overlap.
Librarians help you to manage, organize and revision control a library of re-usable code modules.
Once the ASCII source code text file has been assembled (with an Assembler) or compiled (with a Compiler) and the files have been linked (with the Linker), the output results in a number of files that can be used for debugging the software and programming the actual microcontroller's memory.
A debugger is a piece of software running on the PC, which has to be tightly integrated with the emulator that you use to validate your code. For that reason all emulator manufacturers ship their own debugger software with their tools, but also compiler manufacturers frequently include debuggers, which work with certain emulators, into their development suites.
A Debugger allows you to download your code to the emulator's memory and then control all of the functions of the emulator from a PC. Common debugging features include the capability to examine and modify the microcontroller's on-chip registers, data- and program-memory; pausing or stopping program executing at defined program locations by setting breakpoints; single-stepping (execute one instruction at a time) through the code; and looking at a history of executed code (trace).
So far we've talked about several different pieces of software: Text Editor, Assembler or Compiler, Linkers, Librarians and Debugger. You can easily imagine that it can become quite a time-consuming challenge to alternate back and forth between all of these programs during the debugging process (discover a bug, edit the source code, compile it again, link it again, download the modified code to the emulator, etc.). This is where an integrated development environment (IDE) comes in.
An Integrated Development Environment puts all of the previously discussed software components under one common unified user interface, so that it becomes possible to make a code change and get the modified code loaded into the emulator with a few mouse clicks, instead of dozens. A good IDE allows you for example to click on a syntax error message produced by the compiler and have the source code with the highlighted offending instruction pop up for editing in the text editor. One click of a button and the modified code gets retranslated, linked and downloaded to the emulator. An IDE allows you to store the configuration settings for a project - like compiler switches, or what flavor of chip to emulate - so you can easily recreate a project later on. Some IDEs are flexible enough to allow you to incorporate different choices of third party tools (like compilers and debuggers), others only work with a manufacturer's own tool chain.
When it comes to debugging your code and testing your application there are several different tools you can utilize that differ greatly in terms of development time spend and debugging features available. In this section we take a look at simulators, microcontroller starter kits and emulators.
Simulators try to model the behavior of the complete microcontroller in software. Some simulators go even a step further and include the whole system (simulation of peripherals outside of the microcontroller). No matter how fast your PC, there is no simulator on the market that can actually simulate a microcontroller's behavior in real-time. Simulating external events can become a time-consuming exercise, as you have to manually create "stimulus" files that tell the simulator what external waveforms to expect on which microcontroller pin. A simulator can also not talk to your target system, so functions that rely on external components are difficult to verify. For that reason simulators are best suited to test algorithms that run completely within the microcontroller (like a math routine for example). They are the perfect tool to complement expensive emulators for large development teams, where buying an emulator for each developer is financially not feasible.
Starter Kits, commonly bundle a hardware board and in-system programmer with some software components (assembler, linker, debugger, sometimes an IDE and a code-size limited "evaluation" version of a compiler), to allow for very basic emulation and debugging functions. These kits are most predominant with Flash based microcontrollers. The Flash memory allows an actual sample of the microcontroller to be used to "emulate" itself, by using the included in-system programmer to download the code into the Flash and execute it.
To enable some basic debugging, those kit's need to download a small piece of monitor code along with your own code. This monitor code allows you to stop execution (break) and examine memory and of course uses some of the microcontroller's resources (interrupts; stack-, code- and data-memory; some pins). That's why this approach is called intrusive or non-transparent emulation.
Included with the starter kits is an evaluation board, whose main purpose it is to get you started on your development quickly without the need to develop your own hardware board. The board is typically equipped with a sample of a microcontroller to allow you to execute and evaluate your code. The kits also support the capability to hook up your own hardware if you prefer a setup closer to your final application.
Do not confuse the evaluation boards with a FLASH or OTP production programmer. Even though the kits offer programming capability, the microcontroller sockets on the boards are not built to withstand hundreds or thousands of insertions and are also not equipped with a socket for all controller packages (sockets only for DIP/PLCC packages, but not for SO or QFP packages).
A big advantage of these kits over simulators is that they work in real-time and thus allow for easy input/output functionality verification. Simulators on the other hand offer typically much more powerful debugging features that rival those of high-end emulators. Starter kits, however, are completely sufficient and the cheapest option to develop simple microcontroller projects .
An emulator is a piece of hardware that ideally behaves exactly like the real microcontroller chip with all its integrated functionality. It is the most powerful debugging tool of all. A microcontroller's functions are emulated in real-time and non-intrusively.
All emulators contain 3 essential functions in different implementation forms:
Most emulators give you a range of choices of exchangeable pin adapters and emulation devices to built your own customized emulator that supports the exact derivative and package of your specific microcontroller.
An emulator in my definition always works transparent or non-intrusive (of course some emulator manufacturers will disagree). This means none of a microcontroller's on-chip resources or I/O pins are lost due to emulation. If emulation is not transparent, then it's not an emulator, but an evaluation, development or starter kit. If you are developing projects of medium to large complexity, a non-intrusive emulator will save you lots of time and grey hair.
Because, depending on memory technology, a microcontroller's program memory can not (ROM) or only once (OTP) be programmed, an emulator uses external static RAM as the emulated micro's program memory. Even some Flash based microcontrollers can, depending on manufacturer, only be re-programmed 100 to 1000 times, which warrants the use of external RAM memory rather than the micro's integrated Flash for emulation. RAM memory allows for code to be changed quickly and an "indefinite" number of times during the software debugging process.
As higher-end emulators typically use external RAM memory as program memory, it becomes apparent that in some instances they can not use a standard sample of the emulated microcontroller for emulation purposes. They need special bond-out chips of the microcontroller to be emulated. Those bond-out chips have additional pins that allow the emulator electronics to feed the externally stored program information to the microcontroller in place of the on-chip memory contents in real time; control the program execution flow; and access on-chip registers and data memory.
Instead of special bond-out chips, some emulator manufacturers program a microcontroller's complete functional model into a PLD (programmable logic device). A drawback of this approach is that you never know how accurate the PLD model of the microcontroller is compared to the "real thing". It only works in real-time with models of less complex and slower microcontrollers. On the plus side such an emulator can easily be reconfigured to support many different derivatives of a microcontroller family.
Contributing to the cost of emulators is the control logic required to recreate functions that might be lost due to the emulator using those resources (e.g. some standard I/O pins). By recreating such functions with additional logic, those emulators work truly transparent or non-intrusive, which means you have all the pins, all the memory and all the peripheral functions available like with the real microcontroller.
Even more control logic is required to implement high-end emulator features like complex breakpoint trigger conditions, external event trigger conditions, loop counters, trace memory and in some cases even logic analyzer functions.
Existing emulators today use one of several approaches to emulation, which we
will cover in the following sections.
Many emulators consist of a base unit and a "probecard". The base unit is connected to a PC via the serial, parallel or USB port. It contains the majority of the emulator electronics, with the exception of the emulation chip itself. The emulation chip is a special bond-out version of the actual microcontroller and is mounted on a separate small PCB, called a probecard. This probecard connects via a ribbon cable to the base unit and has a pin adapter at the bottom, which allows the probecard to be plugged into a socket on the actual target application board in place of the actual microcontroller.
The advantage of partitioning the emulator into a base unit and separate probecard is that one and the same base unit can support many different derivatives of a given microcontroller architecture (e.g. all 8051 devices).
By purchasing different probecards the emulator can then be changed to support all the on-chip features and packages of your specific microcontroller derivative(s) of choice. Another advantage is that the probecard can be kept relatively small, which makes it easier to plug it into the target in space constrained applications.
The probecard approach also minimizes the physical distance of the emulation chip from the location of the final microcontroller, minimizing the impact of noise and additional capacitive/resistive loading that can become issues when analog peripherals need to be emulated.
The “debug board” approach combines all of the emulator electronics and the actual emulation chip onto a single, larger sized PCB. This PCB is typically not housed in an enclosure to save cost.
The connection to the target system is accomplished by ribbon cables, which provide, on one end, a connector that can plug into an actual chip package socket of the target system. This means that all pin signals for the microcontroller to be emulated are now routed via this ribbon cable that connects the target system with the debug board, including any analog signals to be measured by the microcontroller. This is a less than desirable solution if your micro has for example high resolution A/D converters and you'd like to make accurate measurements also during emulation.
DBMs are in most cases dedicated to emulating a single specific microcontroller and can not be modified to support other derivatives of a family. If you want to emulate a new derivative you have to buy a new DBM. On the plus side DBM's are typically priced lower than emulators using the probecard approach. DBM's emulation and debugging capabilites often range above starter kits, but below probecard based emulators, with certain exceptions being the rule (DBM has all the features of high-end probecard emulator).
There are several variations of the concepts discussed above on the market. One such variation is to put probecard and base unit into a single enclosure. The "base unit" in that case is a "motherboard" and the probecard a "daughtercard" that connects onto the motherboard. This combination then directly plugs into the target board via a matching pin socket adapter at the bottom. These emulators can still be adapted to emulate different derivatives by exchanging the daughtercard.
Then there are several forms of the "dedicated emulator", which only supports a very narrow range of microcontroller devices (usually micros with identical functionality and pinout, but different memory sizes).
In some implementations dedicated emulators are nothing more than a Debug Board Module, in others take the form of base unit and probecard with the probecard not being exchangeable. A third variant combines base and probecard onto a single non-exchangeable PCB (with or without enclosure) that can directly plug into the target system.
With the advent of FLASH program memory a new approach in microcontroller emulation became possible. The electrical erase/write capability of FLASH program memory, in combination with emulation support circuitry and code embedded in the microcontroller, enable each such microcontroller to be its own emulator. Unfortunately this does not work with all FLASH micros on the market today; especially earlier generation FLASH devices lack the necessary on-chip emulation support circuitry.
Flash microcontrollers that have the necessary on-chip emulation support can, regardless of package, be directly soldered into the target application. This, of course, means that now the microcontroller chip “sees” the exact same analog environment as the finalized application - a big advantage when it comes to accurately emulating on-chip analog peripherals.
The only connection now required to enable PC based software debugging are a few fully digital I/O pins of the controller. The "normal" digital function of those I/Os is “recreated” on a small piece of hardware that sits between the PC and the target system, so that none of the controller's I/Os is lost.
One common on-chip emulation interface for this kind of emulators is the JTAG interface, mostly found on 16-bit and higher microcontrollers. 8-bit devices frequently feature proprietary interfaces to save on cost.
As opposed to emulators for ROM and OTP devices, Flash emulators do not require RAM memory to store the program code, but use the microcontroller's on-chip FLASH memory. This further saves cost and makes those emulators cheaper.
A disadvantage of using the FLASH memory is that program downloads (required after every code change) take much longer. The microcontroller's FLASH memory life-time is limited. Depending on manufacturer, the number of write/erase cycles the memory can withstand varies anywhere between 100 and 100.000 cycles.
On the plus side, FLASH emulators at the same time also double-function as a FLASH programmer, as the program code has to be downloaded into the chip's memory. Emulators for OTPs or ROMs (than can of course also support the FLASH version of a pin/function compatible device, but then in combination with external program memory), do not support any programming functions.
Another advantage of FLASH emulators is the fact that one and the same emulator can support all Flash derivatives of a given microcontroller architecture. If a new device with new functionality comes out, all you need is a sample of that new device and an update of the debugger software. No more need to buy new probecards or debug modules for each new derivative.
It can't be stretched enough: A starter kit or emulator are no substitute for a production grade programmer. Using the microcontroller sockets on starter kit boards is ok to program one or two samples in the lab, but those sockets can not withstand hundreds or thousands of insertions. You will also find that starter kits do not include any sockets for surface mount devices, as those sockets are extremely expensive.
OTP microcontrollers are typically programmed out-of-circuit. That means the microcontroller is programmed before being soldered on the target board. For that purpose production grade programmers offer a choice of optional, high quality, expensive, zero-insertion-force (ZIF) pin adapters to support different package flavors.
FLASH microcontrollers can be programmed both in-circuit (in-system) and out-of-circuit.
With in-circuit programming the microcontroller is already soldered into the target system and can be programmed via one of its communication interfaces (UART, SPI). This requires that you have the signals required for programming routed to an in-system-programming (ISP) connector to which an ISP programmer can be hooked up. The ISP connector required varies from manufacturer to manufacturer and microcontroller to microcontroller, so it is recommended that before you start your PCB layout, you decide on which ISP programmer you want to use and find out which ISP connector is required for it.
As ISP programming is done via a serial interface it is slower than out-of-circuit programming that uses parallel data transfers - something you might want to consider if you have to program 100 000 devices.
One big advantage of ISP programmers is the fact that they do not require expensive ZIF socket adapters. All you need is the ISP connector on your board and the microcontroller soldered onto the board to program even the most exotic package.
Having an ISP connector on your board is a good idea - even if you use out-of-circuit programming for production. It enables you to do painless firmware updates or last minute bug fixes without having to disolder the microcontroller first.
If you now feel you're ready to plunge into the world of embedded systems development, a good place to start exploring a large selection of microcontroller tools from various manufacturers and for many different microcontroller architectures is "The Microcontroller and Embedded System Store".
Email us with
questions or comments about this web site.