Page 197 - Embedded Microprocessor Systems Real World Design
P. 197
a port bit each time an interrupt or timecritical task occurs, then have it continu-
ously reset by the idle loop. If interrupts are nested (see Chapter 5) or if one time-
critical task calls another, the bit will be set twice, which would not affect it. The
idea is to get the bit to be low only when the code is in the idle loop. The ratio of
high to low time, as seen on an oscilloscope, gives a fairly good representation of
the utilization. The changing ratio can be monitored while the system runs. Since
modern emulators can perform this function very well, I would only recommend
the port-bit method if an emulator is unavailable or cannot be used for one of the
reasons mentioned earlier.
Circular Trace Buffers
Sometimes it is impractical to add debug hardware or trace in real time. In these
cases, some trace capability can be implemented with a rotating trace buffer. This
is an area of memory written by the software with action codes, similar to the hard-
ware trace function.
The data area is configured as a circular buffer. When data are written to the
last location, the pointer wraps around to the first position. The size of the buffer
depends on how many trace points are needed and how far back the history needs
to go. Table 6.2 shows a short (16-byte) trace buffer that might be used to debug
a simple system. The table shows 8-bit hex codes and comments indicating what
each code is for.
In this example, the code writes a byte to the table for each trace value, then
writes OFFh to the next table location. When the last table location (000F) is
reached, writing wraps back around to location 0000. In this example, location 0004
contains FF, so the last entry in the table is 01, timer interrupt entry, at location
0003. The history goes back from there. Note that the timer interrupt occurred
between the start and end of output processing at locations OOOC through OOOF.
There usually will be a table pointer in another location, and it also can be used
to keep track of the end of the table. Either way, the engineer or some software
must analyze the pointer or table values to find the end of the table. If this tech-
nique is used, it is best implemented with a single subroutine that writes to the
buffer and updates the pointer or pointers. When the pointer reaches the end of
the buffer, it must be wrapped back to the beginning. Using a circular buffer means
you do not have thk. data captured in a logic analyzer, where it could be correlated
with real-world events.
Data can be time tagged in the trace buffer if a clock is available. One way to do
this is to have a free-running hardware timer and store the count in the trace buffer
with each action code. Some subtraction will determine relative times. Of course,
the timer eventually will roll over, so you must take that into account as well.
178 Embedded Microprocessor Systems