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
   192   193   194   195   196   197   198   199   200   201   202