SYS/BIOS FAQs

From Texas Instruments Embedded Processors Wiki

Jump to: navigation, search
Translate this page to   

Contents


1 Making a debug-able Custom SYS/BIOS Library

By default, the following setting:

BIOS.libType = BIOS.LibType_Custom;

will generate a highly optimized, minimally debug-able custom SYS/BIOS library that your application will link with.

The optimizations are achieved by including the "-o3" compiler option during the compilation phase.

This aggressive optimization setting results in very efficient code at the expense of debug-ability.

To create a custom library that is more debug-able, you can modify the optimization setting by adding the following line to your config script:

BIOS.customCCOpts = BIOS.customCCOpts.replace("-o3","-o0");

This will change the optimization level from "-o3" to "-o0". (You can replace "-o0" with whatever setting you want).

For ARM targets (ie 'M3', 'A8Fnv', 'Arm9'), you should also add the following line to your config script to remove the "--opt_for_speed=2" compiler option:

BIOS.customCCOpts = BIOS.customCCOpts.replace("--opt_for_speed=2","");

Note: This modification will result in much slower SYS/BIOS performance as well as a larger code footprint.

To view the set of compiler options used to create the custom SYS/BIOS library, add the following to your config script:

print(BIOS.customCCOpts);

Note: Whatever you do, DO NOT REMOVE the "--program_level_compile" compiler option from BIOS.customCCOpts.

Note: The 'BIOS.libType' option was added in 6.32.01

2 Removing Asserts from the Custom SYS/BIOS Library

Runtime Assert checking is very useful during application development. However, there is a significant performance penalty associated with them. Once your application is up and running to your satisfaction, you can remove the runtime Assert checking code from the custom SYS/BIOS library by adding the following line to your config script:

BIOS.assertsEnable = false;

This configuration parameter only applies when you are using the custom SYS/BIOS build option:

BIOS.libType = BIOS.LibType_Custom;

Note: The 'BIOS.libType' option was added in 6.32.01

3 Placing SYS/BIOS code in different memory segments

Placing SYS/BIOS code in different memory regions can be done by adding a secondary .cmd file to your project. The linker can handle more than one .cmd file. Placing interrupt-related code and scheduler code in on-chip or L2 memory can help in systems with tight latency requirements since this code will always be "close" to the CPU and not out in slower off-chip memory. The cache will try to keep code in L1/L2, but forcing time critical code to L2 RAM will help. The L2 memory can be split between Cache and RAM and on some devices there is dedicated L2 that cannot be used for cache.

SECTIONS
{

   /* place all the knl APIs in IRAM */
   .knl: { *.*(.text:*ti_sysbios_knl*) } > IRAM
  
   /* place all the Hwi APIs in IROM */
   .hwi: { *.*(.text:*ti_sysbios*_Hwi_*) } > IROM
  
   /* place the remainder of the SYS/BIOS APIs in DDR */
   .sysbios: { *.*(.text:*ti_sysbios*) } > DDR
      
}

Similar functionality can be achieved by adding the following Program.sectMap[] commands to your config script:

/* place all the knl APIs in IRAM */
Program.sectMap[".knl: { *.*(.text:*ti_sysbios_knl*) }"] = IRAM;
  
/* place all the Hwi APIs in IROM */
Program.sectMap[".hwi: { *.*(.text:*ti_sysbios*_Hwi_*) }"] = IROM;
 
/* place the remainder of the SYS/BIOS APIs in DDR */
Program.sectMap[".sysbios: { *.*(.text:*ti_sysbios*) }"] = DDR;

4 Exception Dump Decoding Using the CCS Register View

SYS/BIOS provides several target unique exception handlers:

ti.sysbios.family.arm.exc.Exception     /* used by all Arm9 and A8 targets */
ti.sysbios.family.arm.m3.Hwi            /* used by all cortex-M3 targets */
ti.sysbios.family.c64p.Exception        /* used by all C6x targets */

By default, beginning with the 6.32 SYS/BIOS releases, all of these exception handlers print a complete register context dump to the CCS console when an exception is detected.

If you copy the exception dump's values for the PC, SP, (and LR for ARM targets) into the corresponding registers in the CCS register view, CCS will usually provide a very useful call stack back trace in the debug window.

For example, below is a snaphot of CCS just after an exception has occurred on a Stellaris LM3S8962 evaluation board (Cortex-M3):

ExceptionBefore.jpg

And here is a snapshot after the PC, SP, and LR register contents were copied from the exception dump into the CCS register view. Notice the call stack backtrace in the debug window.

ExceptionAfter.jpg

5 Using CCS and ROV to view a core dump file

If you can get your data memory into one or more COFF/.out files, you can use CCS and ROV to review the core dump. You need to have the original .out file and the 'rov.xs' file associated with the given .out file. The rov.xs file is usually in the configPkg/package/cfg directory in your CCS project.

Step 1 is the hard part. You need to get your data memory into a COFF file. On architectures with cache, reading external memory is not enough. You have to first flush the cache to get the data out to external memory. If you are using CCS, this is not an issue since CCS reads the memory using CPU view so it looks through the cache just like CPU would. Here's a screen shot showing how to save a block of RAM from the CCS Memory window:

Coredump1.jpg

Step 2 is to start CCS and connect to an active board or simulator with the same data memory configuration (or super-set) as the application you want to analyze.

Step 3 is to load the memory files using the "Load Program" option. Note that you are loading COFF files to simply fill the data memory. These COFF files do not have any symbol information.

Coredump2.jpg

Step 4 is to load the symbols from the corresponding .out file using "Load Symbol" option. Here you are only loading the symbols from the COFF file and are not loading any code or data from the file. This is important since you do not want to disturb any of the data from the core dump files you saved in step 1 and loaded in step 3.

Coredump3.jpg

You should now be able to open ROV and look at the assorted modules for clues about the state of the system at the time the core dump was taken.

Coredump4..jpg

That's It!

6 Overriding the default Timer frequency

To override the default Timer frequency used by SYS/BIOS to calculate the configured timer period (for the ti.sysbios.timers.dmtimer.Timer module):

/* set the Timer frequency to 20MHz */
var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
Timer.intFreq.hi = 0;
Timer.intFreq.lo = 20000000;

Note, this article contains more DM Timer details specific for TI81XX devices.

7 How to build SYS/BIOS apps on Linux using an external makefile

See attached example.tar.gz file File:Example.tar.gz for an example of how to build 3 sample SYS/BIOS apps using a makefile. For this example, we build a single configuration using the configuro tool. And we use this common configuration for all 3 sample projects. You can also have separate configuration for each project or a mix. This example is tailored for the Stellaris platform, but can be updated for other platforms. You can get the Linux version of the XDC tools and SYS/BIOS on the external download page: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/index.html

8 Making an Error site’s file name available to an Error raise hook

By default, SYS/BIOS modules are built such that the file name of the site where an Error is raised is not accessible to a registered Error raise hook (xdc_runtime_Error.raiseHook). In other words, by default, the modules are built such that xdc_FILE is NULL, so the file names are optimized out. [See the description of xdc_FILE in “Controlling File Name Strings” here: http://rtsc.eclipse.org/docs-tip/Integrating_RTSC_Modules]. To have the file name accessible to the Error raise hook, the SYS/BIOS libraries need to be rebuilt with xdc_FILE=__FILE__.

The easiest way to do this with SYS/BIOS v6.32 or later is to use the Custom build type (i.e., BIOS.LibType_Custom, as described under “Compiler and Linker Optimization” in Bios_User_Guide.pdf), and specify xdc_FILE via a compiler option. You can do this by adding statements like the following to your application configuration script:

BIOS.libType = BIOS.LibType_Custom;
BIOS.customCCOpts += " -Dxdc_FILE=__FILE__ ";

For other (non BIOS.LibType_Custom) application builds, the alternative is to rebuild the SYS/BIOS libraries as described in Appendix B of Bios_User_Guide.pdf, with the additional specification of xdc_FILE=__FILE__.

9 Overriding the SYS/BIOS source subdirectory for BIOS.LibType_Custom

By default, BIOS.LibType_Custom builds will create a “src” subdirectory in a CCS project as a work area for rebuilding the relevant SYS/BIOS modules. To override this subdirectory name (because you want to use “src” for something else), you can add the following to your application configuration script:

BIOS.libDir = “newDir”;

You can replace “newDir” with a different name of your choice.

10 Example showing how to add Task hooks to the system

SYS/BIOS allows users to add their own application specific task hooks to the system. These hooks will be called at key points during thread lifecycle (create, delete, switch, exit, etc.). See the SYS/BIOS User's Guide and APIs for more info. This example shows how to add these hooks in the .cfg file (Task.addHooks()) along with sample C code for sample hook functions. The sample app is similar to the mutex example that ships with SYS/BIOS, but a call to Task_delete() has been added to exercise the delete() hook.

Add this to your .cfg file:

Task.addHookSet({
    registerFxn: '&myRegisterFxn',
    createFxn: '&myCreateFxn',
    deleteFxn: '&myDeleteFxn',
    switchFxn: '&mySwitchFxn'
});

And these sample implementations to your .c file:

#include <xdc/std.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/knl/Task.h>
/*
 * Task Hook Functions
 */
#define TLSSIZE 32
Int hookId;
/*
 * ======== myRegisterFxn ========
 * This function is called at boot time.
 */
Void myRegisterFxn(Int id)
{
     hookId = id;
}
/*
 * ======== myCreateFxn ========
 */
Void myCreateFxn(Task_Handle task, Error_Block *eb)
{
    Ptr tls;
    System_printf("myCreateFxn: task = 0x%x\n", task);
    Error_init(eb);
    tls = Memory_alloc(NULL, TLSSIZE, 0, eb);
    
    Task_setHookContext(task, hookId, tls);
}
Void myDeleteFxn(Task_Handle task)
{
    Ptr tls;
    System_printf("myDeleteFxn: task = 0x%x\n", task);
    tls = Task_getHookContext(task, hookId);
    Memory_free(NULL, tls, TLSSIZE);
}
Void mySwitchFxn(Task_Handle from, Task_Handle to)
{
    // System_printf("mySwitchFxn: from = 0x%x, to = 0x%x", from, to);
}
Leave a Comment
Personal tools
Namespaces
Variants
Actions
Navigation
Print/export
Toolbox