EDN Access PLEASE NOTE:
FIGURES WILL LINK
TO A PDF FILE.

April 23, 1998


Debugging embedded systems:
using hardware tricks to trace program flow

Stuart R Ball

If your embedded system is too small to provide even a trace buffer or a serial port as debugging aids, you can use a variety of hardware tricks to observe your program's activity.

A trace buffer is a valuable debugging aid. It provides a history of your program's behavior by recording explanatory "action codes" whenever your program reaches certain key points in its execution (Reference 1). In some small µC-based designs, however, you might not have enough memory to implement a trace buffer. Likewise, your system may not have a serial port that could aid debugging by transferring data back and forth between the system and a PC. You can still track your program's execution flow in such a minimal system, however. One way is by writing data to an unused memory or I/O location and capturing it on a logic analyzer in state mode. The analyzer's memory, in effect, serves as a trace buffer.

09DESP21An illustration of tracing with 80188-based hardware appears in Figure 1. A 74ACT138 3-to-8-line decoder decodes the low order address from a 74ACT373 latch. PCS2 and WR (from the 80188) enable the 74ACT138. On the 80188, the PCSx lines are active for 128 contiguous addresses, and they may map into either memory or I/O space.

09DESP22For purposes of illustration, assume that PCS2 is active (low) for all I/O addresses in the range 100 to 17F hex, or 512 to 639 decimal. As shown, the circuit uses Y0, Y1, and Y2, leaving the remaining lines free. Y7 provides a signal called ­TRACE WR that doesn't connect to any system hardware, but can serve as a strobe to a logic analyzer's clock input. Because the 74ACT138 decodes lines A3 through A5, Y7 is active at addresses 138 to 13F hex. If the software writes action codes to address 138, and if Y7 (­TRACE WR) is connected to a logic analyzer's clock input (Figure 2), the logic analyzer can pick up the codes and store them.

Time tags and other data

Of course, you might want to store more than action codes in some cases, just as you might if you had a trace buffer in your embedded system's memory. Time tags, for example, can provide valuable information for debugging. Fortunately, most modern logic analyzers can time stamp captured states, so your software doesn't have to. And you, in turn, don't have to keep track of trace-buffer memory pointers, which you would need to do if you were mixing action codes that stand alone and action codes that have time tags associated with them. Of course, you still need a way to distinguish action codes and data if the data contains anything other than time information.

A slight change in the logic-analyzer connection can make it easy to separate action codes and data. To see how, note that in Figure 1, the ACT138 decodes only A3, A4, and A5 (a partial decode) of the address bus, so each line is active for more than one address. For example, Y0 (pin 15) is active for addresses 100 to 107, and again from 140 to 147, 180 to 187, and 1C0 to 1C7. Table 1 shows the address ranges for which the ACT138 decoder's outputs become active. Remember that, on the 80188, PCSx lines are active for 128 contiguous addresses.

09DESP23Figure 3 shows how you can connect a logic analyzer to take advantage of this situation. As in Figure 2, Y7 serves as a diagnostic strobe, connected to the logic analyzer's clock input. Data capture still occurs on the analyzer's pod 1. However, Figure 3 adds A0 from the 80188 address latch to the logic analyzer, connecting it to channel 8. Now, when you want to write an action code, you write it to address 138 (hex) as before. But, if you want to write additional diagnostic data, you write it to address 139 (hex). Figure 3 includes an example display.

With the connections of Figure 3, writing to address 138 toggles the ­TRACE WR signal, clocking data into the analyzer as with the connections of Figure 2. Writing to address 139 also toggles the ­TRACE WR signal and clocks data into the analyzer, but with the A0 line high. As a result, you can tell the difference between an action code and an action code's accompanying data. You can even attach more than two bytes of data with selected action codes, because you can always find the action code corresponding to a stream of data bytes. Just look backward in the analyzer buffer for the write with A0=0. Note that, instead of connecting A0 to the analyzer and writing action codes and data to 138 and 139, respectively, you can achieve the same result by connecting A6 to the analyzer and writing action codes and data to 138 and 178, respectively.

The concept of writing to unused addresses will work with any processor that uses an external data bus and decodes addresses to generate write strobes to external hardware. Sometimes, though, there is no address-decode logic or there are no unused strobes. Or, perhaps, some other situation prevents you from using a decoded write strobe to trigger your analyzer. In this case, there are other tricks you can use to generate a strobe for trace data. One way is by writing to ROM.

Using ROM space

In most embedded systems, the only thing in the ROM space is the ROM itself. However, the address-decoding logic often does not differentiate between a read and a write, so if you write your trace data to the ROM space, it usually will not affect any hardware. Use caution, though. Make sure the address-decode logic doesn't turn on the ROM outputs when you write to that address range, or you'll have bus contention. And, if you're using a nonvolatile memory such as EEPROM, be sure that a write to the ROM space won't change the contents of the memory.

09DESP24In the partial schematic of Figure 4, the circled logic gates decode a write to ROM space and generate a strobe to clock trace data into an analyzer. As before, the trace clock has the label ­TRACE WR. The circled logic could be a permanent part of your circuit board, or you could connect it to your board with a DIP clip when necessary. When using the write-to-ROM scheme for Motorola-type processors, which need an ACK signal to terminate the cycle, make sure the PROM decoding logic generates the ACK on both reads and writes.

09DESP25On some microcontrollers, such as the 8031, you can't write to ROM space. However, if you're not using all the ROM space, you can accomplish your objective by reading from ROM. In Figure 5, the 27256 EPROM requires 32k of the 64k address space, so you can decode any read from the upper 32k (A15=1) as a trace output. The circled gates in Figure 5 provide logic for generating a logic-analyzer write strobe from a read-from-ROM operation. 09MXXXAListing 1 shows the necessary program code. Note that the logic analyzer takes trace data from the low order address lines.

Whatever scheme you use to generate trace-output signals, you can simplify hookup by adding a connector for these signals to your board's design. A 10-pin inline header works well with 8-bit processors; a dual-row header is good for 16-bit designs. Eight (or 16) pins connect to the data lines, one connects the write strobe, and one serves as ground. You can also add an edge connector on one side of the board. If board space is at a premium, you can add a row of pads and access the test points with a fixture containing spring-loaded "pogo pins" of the type used in bed-of-nails testers.

09DESP26Another debugging aid is the use of LEDs as status indicators (Figure 6). The LEDs typically connect to a register output (in the figure, pin 19 of a 74AC374 flip-flop) or a port pin. When connecting an LED to some µPs, you need to add a drive transistor, because the µP's output sink current is insufficient for adequate LED brightness. In the figure, an LED connects to pin 8 of an 8031 through a MOSFET. If you use a bipolar LED, as shown connected to pins 2 and 5 of the 74AC374 in the figure, the LED can glow either red or green to indicate different status conditions:

Pin 5

Pin 2

LED color

0

0

off

0

1

green

1

0

red

1

1

off

If the pins toggle quickly between the 10 and 01 states, the LED can also display an amber color.

09MXXXCA single software-controlled LED on a board can serve as a good/bad indicator--useful for indicating which board in a malfunctioning system needs replacing. Often, though, you'll want a more detailed idea of what went wrong. One way to supply this additional information is to flash an error code on an LED. Listing 2 shows how to do this on an 8031, although the technique will work for any processor.

Listing 2's code turns an LED on for about one second as a start indicator, then flashes the LED quickly to indicate the most significant error-code digit and then more slowly to indicate the least significant digit. To read a two-digit error code, look for the start indication, count the slow flashes, and then count the fast flashes. (For ease in counting and remembering the flashes, implement error codes in which neither digit has a value greater than five.) Listing 2's 8031 code is suitable as a display-and-hang error handler. If you want the processor to keep running, servicing interrupts, or communicating with a display, you can implement the LED flashes as part of a regular tick interrupt service routine.

The software listings in this article are available by clicking here:
download 09msdesp2


Reference

  1. Ball, Stuart, "Debugging embedded systems: using a trace buffer to see what went wrong," EDN, April 9, 1998, pg 161.

  2. This article, one of an occasional series on basic debugging techniques, is an adaptation from the book, Debugging Embedded Microprocessor Systems by Stuart R Ball. Material reproduced courtesy of Newnes, an imprint of Butterworth-Heinemann, 225 Wildwood Ave, Woburn, MA 01801-2041. For more information, check www.bh.com. To order, call 1-800-366-2665.


Author's biography

Stuart Ball, PE, is an electrical engineer who has spent the last 16 years designing digital, analog, and embedded-µP systems. He is the author of two books, Embedded Microprocessor Systems: Real World Design and Debugging Embedded Microprocessor Systems, both published by Newnes (Woburn, MA). He is currently employed at Organon-Teknika (Oklahoma City, OK), a manufacturer of medical instruments.


| EDN Access | Feedback | Table of Contents |


Copyright © 1998 EDN Magazine, EDN Access. EDN is a registered trademark of Reed Properties Inc, used under license. EDN is published by Cahners Business Information, a unit of Reed Elsevier Inc.