Tics Realtime -----


 
Home Services Products Tutorials Contact Us
- - - - -

Debugging with an In-Circuit Emulator

This article describes how an ICE can be used to debug real-time embedded applications.

What is an ICE?

An ICE is a piece of electronic test equipment that is used to debug hardware and embedded software.

Why a Standard Software Debugger is not Enough

A standard software debugger is not useful under certain situations, such as:

  1. Debugging code in EPROM - Software debuggers typically set a breakpoint by over-writing the target instruction with an instruction that will cause an exception to occur (for example an illegal instruction will generate an exception or interrupt). The debugger will receive the exception interrupt, handle the breakpoint, restore the original instruction, then continue. The problem is that this will not work with EPROM since EPROM is not writable.
  2. Diskless systems - Most debuggers are not designed to work stand-alone on a diskless embedded board - they need access to the disk for symbol table files, source files, and the like. Furthermore, debuggers are usually designed to run under a specific OS, which is typically not available on the target board.
  3. New hardware and software - When debugging software on a newly designed board it is sometimes difficult to tell whether the bugs are due to hardware or software problems. An ICE can assist in this situation.
  4. Hard to solve problems require more sophisticated debugging capabilities, as outlined below.

How an ICE Works

The ICE itself is basically a box with a cord extending from it which is terminated with a probe. The probe is a small circuit board that contains the same CPU as the target board. The ICE is connected to the target board by removing the target board CPU and replacing it with the pin compatible probe. This arrangement allows the software to run on the CPU as normal, with the additional monitoring and other capabilities of the ICE.

ICE Debugging Capabilities

The fact that the ICE monitors CPU activity makes for some powerful debugging capability. For example.

  1. Since the ICE monitors the address and data lines you can set some powerful breakpoints. For example, (a) break when a certain address is accessed, (b) break when a certain address is accessed but only if a data value of "n" is written, (c) break only on the read of an address, (d) break when any address in a range is accessed, and any number of other combinations of address, data, read/write and other CPU status.
  2. The ICE typically has its own memory which can be "mapped" in part or in whole onto your target board. This means that, for example, you can instruct the ICE to force all memory references to access internal ICE memory, instead of memory on your board. This can be useful in testing memory problems and when there is no RAM on the board under test. However, it is most useful for mapping EPROM to internal ICE memory, which allows you to check out whether the hardware is addressing EPROM memory correctly and run downloaded code out of the EPROM memory space.
  3. Since the ICE monitors every CPU cycle, it can save the last "n" instructions in a trace buffer. This allows one to view the execution history which can be useful during debugging. Some emulators may also allow for selective trace, e.g., "trace only on writes to a certain address range".
  4. ICE's often have general purpose wires that can be connected to various pins, I/O's, etc. The state of these wires can then be used in breakpoint and trace assignments. For example, "when wire0=1 and wire5=0 and AddressInRange(1024,2048) then break;". This is useful because sometimes you may want to break only when certain conditions external to the CPU are met.
  5. Some ICE's allow you to jump to a particular address to execute your own special debug code when certain conditions are met. You can think of this as an interrupt which is triggered by a set of conditions previously set. When control is transferred to your code you can test for various conditions that are not possible with ICE commands.

ICE Command Language

Most ICE's have some form of command language that allows you to specify how and when a break or trace should occur. For example, "WHEN ADDRESS >= 1024 && ADDRESS <= 2047 && DATA > 5 && DATA < 10 THEN BREAK". Each ICE typically has its own command language.

Summary and Comments

The ICE is a powerful and essential tool for debugging embedded software. See the following article "Debugging with an In-Circuit Emulator" to see how these powerful features are applied.


We welcome comments. Let us know what subjects you would like written up. Send comments to mike@Ticsrealtime.com

Copyright © 1992-2004, Tics Realtime