Accessing DSP BIOS logs without JTAG

From Texas Instruments Embedded Processors Wiki

Jump to: navigation, search


  • Image:Google-16x16.png Search for an article here:


D== Accessing DSP BIOS logs without JTAG ==


Many developers use the DSP BIOS LOG_printf() or LOG_event() functions to instrument their applications with debug information. In many cases, especially for telecom or video infrastructure applications, developers may wish to leave the instrumentation in the production code base to enable easier isolation of errors that occur in testing laboratory or field trial situation. One challenge is such situations is that access to DSP BIOS logs generally requires an emulator to be connected to the malfunctioning DSP. This may be physically impossible in densely-packed board racks or practically impossible if the equipment is at a remote customer site.

Although some recent DSP devices (DM6437 and DM648) enable DSP BIOS logs to be retrieved over TCP/IP for viewing in the SoC Analyzer, this capability is not available for many DSPs yet. An alternative approach for developers is to write some code that retrieves the logs remotely via whatever communication mechanisms are available to the DSP (often via an host microcontroller) and then displays the log contents either on the developer's desktop or on a debug console attached to the equipment. To achieve this, it is necessary to understand how to access the log buffers and the format of the log records. This information is summarized below.

Contents

Introduction

When a LOG_printf() is executed from your target program, it is written into memory in such a way that the host can grab the entries and output them on the PC. The way the LOG_printf() information is stored is using LOG_Event's in a particular location in memory associated with the log you’re printing to. This location can be found by taking your log name and concatenating a "$buf" to the end of it. For the trace log you would look for the location in memory associated with the following symbol, "trace$buf". One thing to note when looking at this information directly in memory is that it gets cleared by the RTA plugins code when it is read at run time as well as when read via stop mode. The memory location is then filled with 0xF’s to signify that there is no relevant LOG_printf() data in the memory at that location.

Contents of memory address {log name}$buf

Each four word LOG_Event has the following elements in each log buffer entry:

  • ADDR (first word): SEQNUM – sequence number of the particular LOG_printf statement. This number starts at 2 and counts upwards by two (this should be divided by two for sequential numbers).
  • ADDR+1 (second word): Arg0 – argument passed to LOG_printf to be used in conjunction with the format string
  • ADDR+2 (third word): Arg1 – argument passed to LOG_printf to be used in conjunction with the format string
  • ADDR+3 (fourth word): STRING – this is the format string address passed to LOG_printf. This string is stored in the .const/.printf sections of the COFF file. To read the string take the address from the fourth word of the appropriate LOG_Event and read the string at that location in the COFF file up until the NULL character.

The number of LOG_Event entries in the {log name}$buf depends upon the configured size of that particular log buffer. If you wish to look this up you can either reference your .tcf file (also can do through gconf) or grep the COF file symbol table for the {log name}$size symbol and check it’s value (for BIOS 5.10 or later). If you are using BIOS 4.90 or earlier you will need to look directly at the configuration in gconf under the list of logs and reference the properties for the size field of the log in question.There are some exceptions to the above format. The 28x and 55x are slightly more complicated in terms of interpreting the LOG_Events. They generally stick to the above format but have minor variations based upon the addressing size and where the LOG_printf() came from (assembly or C).

Record format on 28x and 55x

There are two main differences in the format of the records on 28x and 55x targets.

1. The records are still 16 bytes each, but the sequence number is only 16-bits instead of 32-bits. The format of a LOG_printf record on the 28x and 55x is as follows:

  • 16-bit pad
  • 16-bit sequence number
  • 32-bit arg0
  • 32-bit arg1
  • 32-bit format address

2. The arguments may be "packed" into the space of arg0 and arg1. When the log record is written, the arguments are copied directly from the stack to the record. For example, if a Log_printf had two arguments, an integer (16-bits) and a pointer (32-bits), the record would have the following format:

  • 16-bit pad
  • 16-bit sequence number
  • 16-bit arg0
  • 32-bit arg1
  • 16-bit empty
  • 32-bit format address

In order to decode the record correctly, you need to know the size of the arguments. This can be done generically by parsing the format string to determine the argument types.

Decoding example for C6x

For illustration purposes we can show how a pseudo-C program on the host could decode a LOG record obtained from a C6000 DSP:

struct LOG_event { 
    UInt32 seq;
    UInt32 arg0;
    UInt32 arg1;
    UInt32 formatPtr;
};

struct LOG_event log;
char chr;
char format[];
int i = 0;

`copy current LOG entry into log`;
do {
    chr = `read a byte from address (log.formatPtr+i) in COFF file`;
    format[i] = chr;
    i++;
} while (chr != '\0');

printf(format, log.arg0, log.arg1); 

The statements in `backticks` above are loosely specified because there are varied methods with which to accomplish those actions. For example, there are utilities (libraries) available with which to read COFF files.


For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Accessing DSP BIOS logs without JTAG here.
Leave a Comment

Comments

Comments on Accessing DSP BIOS logs without JTAG


Thomasward said ...

This is great. However, I am unable to find any information about how to decode these logs myself (not using rtadecode).

--Thomasward 13:00, 1 February 2010 (CST)