Debugging DSPs

Top  Previous  Next

The best way to debug a multiprocessor application is to design it for debugging.

 

While it is common practice to debug a sequential program by observing its behaviour with a debugger, that technique is, at best, tricky when two or three processors are involved, and becomes rapidly unworkable as the number of processors increases. A more structured method is needed.

 

One line of attack is to use tasks as a natural unit for debugging. They are independent of other tasks in the system and so it is usually possible to design dummy modules to connect to them and provide test inputs and check outputs. It is then reasonable to use Texas Instruments’ Code Composer to debug individual Diamond tasks.

 

Code Composer has been designed assuming that a processor can be running only a single program, but Diamond applications are different:

They may have multiple tasks on each processor;

Tasks may spawn multiple threads;

Different tasks may use the same identifiers; for example, every Diamond task has a main function;

There is a kernel executing on each processor;

The kernel  passes control from one task to another as the application executes.

 

This complicates the debugging process a little, but it is still straightforward. You need to be aware of a few things first:


Diamond makes it easy for you to load the symbol tables for one task or all your tasks.

The debugger  switches into assembly language mode if control passes into a system module, the kernel, or a task that has not had its symbol table loaded. You can run to the next breakpoint or try loading the appropriate symbol table: see the next section.  This can also happen if the debugger is unable to locate the appropriate source files. You can add folders for Code Composer to search by visiting Option/Customize.../Directories.

A breakpoint is honoured by any thread reaching it.

Single-stepping can lead to unexpected results if you have breakpoints in other tasks on the processor. For example, if you step over a call that results in rescheduling (printf, for example), you can find yourself on a breakpoint in another thread. Single-stepping there loses the implied breakpoint following the original single-step. If you had set no other breakpoints in the first thread, you may find it tricky to get back to it.

Because of the previous point, you may find it easier to debug one thread or task at a time.