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:
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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".
- 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.
- 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
|