Debugging Overlays With CCStudio

From Texas Instruments Wiki
Jump to: navigation, search

Debugging Overlays With CCStudio

Overlays

When sections of code are configured to share the same run-time address, it is referred to as overlaying of sections of code. This is done to share a small amount of fast memory (commonly referred to as the “overlay region”) among several sections of code. Each of these sections is referred to as an “overlay section”. Each of these overlay sections must be copied from where it has been loaded (often in slower, more plentiful, memory) to the specified overlay region before code in the section can be executed.

Overlays With CCStudio

When you load the *.out file in CCStudio, it will load all the debug symbols associated with the application. If the application uses overlays, there will be several symbols for code sections that reference the same run-time address. This will cause issues when trying to debug the overlay sections. Because several sections of code share the same run-time address, CCStudio can get confused as to which symbol to reference when stepping into/through the overlay region. Many times it will associate the wrong symbols with the current overlay section loaded into the overlay region. When that happens, issues such as the wrong source file will be opened when stepping through that section of code, content in the watch window for locals will be inaccurate, etc… making debugging very difficult. To prevent this from happening, we must ensure that CCStudio will reference the correct symbols associated with the overlay section that is in the overlay region.

The easiest way to do this is to “hide” (to CCStudio) those symbols associated with the non-current overlay section and “show” only the symbols of the overlay section that is currently in the overlay region. This can be done by using some built-in GEL calls provided in CCStudio: GEL_SymbolHideSection() and GEL_SymbolShowSection(). These calls will hide/show symbols for the specified section of code to CCStudio. When these calls are used correctly, CCStudio will associate the correct symbols with the current overlay section, thus allowing proper debugging.

Please note that for debugging with DWARF symbols, the aforementioned GEL calls only will work with versions of CCStudio 3.1 (with Service Pack 1 installed) or greater. The ‘–b’ linker option (Disable Debug Symbol Merge) may also have to be enabled, depending on the version of the code generation tools being used. There are no such limitations with STABS debug symbols.

These GEL functions can be called from the GEL Toolbar. GEL hotmenu items can also be created so that the correct function with the desired parameters can be called at the click of the button. Both steps are a manual process where the developer must explicitly hide and show the proper symbols before trying to debug / source step into the overlay region. There are additional CCStudio/GEL tricks that can be used to help automate the hiding and showing of the correct overlay symbols - such as using conditional breakpoints that call a custom GEL function which will hide and show the correct symbols can be configured.

Example

In this simple example application, there are 3 overlay sections, .fft_scn, dot_scn, dot_scn which all share the same run-time address (0x200):

/* Example linker command file */
SECTIONS
{
	UNION 
	{
		.fft_scn: load = 0x10000, table(_fft_ctbl) 
		.dot_scn: load = 0x12000, table(_dot_ctbl)
		.fib_scn: load = 0x14000, table(_fib_ctbl)
	} run = 0x200

..

The application takes advantage of a new linker functionally called copy tables to help configure and manage overlays. For more detailed information on copy tables, please refer to App Note SPRAA46: Advanced Linker Techniques for Convenient and Efficient Memory Usage.

When we load the application in CCStudio and open the Symbol Browser, we see that symbols for all the overlay sections have been loaded:

Debug overlay symbol browser.PNG


Note that the functions dot() (in .dot_scn), fft() (in .fft_scn) and fib() (in .fib_scn) all share the same run-time address (0x200). To debug any of those functions, we need to ensure that the correct symbols are hidden/shown to CCStudio. Next we set some conditional breakpoints at each location where code in the overlay region is executed:

Debug overlay editor.PNG


I can set the conditions of each breakpoint using the Breakpoint Manager:

Debug overlay BPM CCS31.PNG

Note that the screenshot above shows the Breakpoint Manager from CCStudio 3.1. In CCStudio 3.2 and greater, the Breakpoint Manager has been replaced by the new Unified Breakpoint Manager (UBM) which has a different interface but supports all the same functionality and more.

Each breakpoint has been configured to call the custom GEL expression called ‘DynamicSymbolLoader()’. The parameter passed in is the overlay number attributed to the overlay section currently loaded when that breakpoint is reached. Since we have a separate conditional breakpoint at the location of when a different overlay function is called, we know which overlay section is ‘active’ at that time.

Now let’s take a look at what DynamicSymbolLoader() does:

// You can set a conditional breakpoint in your code to evaluate the GEL
// expression below (DynamicSymbolLoader) when a overlay load occurs. 
// Pass in the "index" to specify which overlay just got loaded when the 
// breakpoint is reached 

// Load symbols for the current overlay section loaded on target
DynamicSymbolLoader(int index)
{
    HideLastOverlaySymbols();   // hide the symbols of the last overlay section

    if ( index == OVERLAY1 )                            
    {
        GEL_SymbolShowSection(SYMBOL_FILE_PATH, SECTION_NAME_1, CODE_START, DATA_START); // show relevant section
        gGEL_lastOverlaySymbolsLoaded = index;
    }
    else if ( index == OVERLAY2 )
    {   
        GEL_SymbolShowSection(SYMBOL_FILE_PATH, SECTION_NAME_2, CODE_START, DATA_START); // show relevant section
        gGEL_lastOverlaySymbolsLoaded = index;
    }   
    else if ( index == OVERLAY3 )
    {   
        GEL_SymbolShowSection(SYMBOL_FILE_PATH, SECTION_NAME_3, CODE_START, DATA_START); // show relevant section
        gGEL_lastOverlaySymbolsLoaded = index;
    }   
    else
    {
        GEL_TextOut("Error! Undefined section specified: %d\n",,,,,index);          
    }
    
    return TRUE;    // if using conditional breakpoints and you wish to halt.
                    // if return != TRUE or returns nothing then the GEL expression
                    // will be evaluated and then prog. execution resumed.
}

// Remove symbols of previous overlay
HideLastOverlaySymbols()
{
    GEL_TextOut("Removing overlay symbols for: %d\n",,,,,gGEL_lastOverlaySymbolsLoaded);    
    
    if (gGEL_lastOverlaySymbolsLoaded == NULL)
    {
        // all symbols loaded (start), hide all overlay symbols
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_1);    
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_2);    
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_3);    
    }
    else if (gGEL_lastOverlaySymbolsLoaded == OVERLAY1) 
    {
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_1); 
    }
    else if (gGEL_lastOverlaySymbolsLoaded == OVERLAY2)
    {   
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_2);
    }   
    else if (gGEL_lastOverlaySymbolsLoaded == OVERLAY3)
    {
        GEL_SymbolHideSection(SYMBOL_FILE_PATH, SECTION_NAME_3);
    }
    else
    {
        GEL_TextOut("No symbols hidden. Undefined section specified\n" );       
    }
}

DynamicSymbolLoader() will first call HideLastOverlaySymbols() to hide the last overlay symbol shown using the built-in GEL call GEL_SymbolHideSection(). If the application has just been loaded, then that means all the overlay symbols are visible, thus all the overlay symbols need to be hidden. The value of the last shown overlay symbol is stored in the global GEL variable gGEL_lastOverlaySymbolsLoaded (with ‘NULL’ or ‘0’ representing ‘all’). Note that global GEL variables is a feature only supported in versions of CCStudio 3.1 and greater.

Once the last overlay symbol that was visible is hidden, DynamicSymbolLoader() will use the built-in GEL call GEL_SymbolShowSection() to show the overlay symbols of the overlay section in the overlay region. It knows which overlay symbols to show by the value passed in to it from the conditional breakpoint. Once the correct symbols are shown, the value of gGEL_lastOverlaySymbolsLoaded is updated it exits the GEL function.

Thus every time a conditional breakpoint is hit, the correct overlay symbols will be hidden/shown to allow debug of the code section in the overlay.

Note that the overlay application is a very simple example. For more complex overlay scenarios, more effort may be needed and it may not be possible to fully automate the hiding and showing of the correct symbols. However the above example should give you a general idea of how debugging overlays within CCStudio can be achieved.