Using xdc.runtime Startup/TI

From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  offline version generated on 18-Nov-2017 00:11 UTC 

Using xdc.runtime Startup/TI

How Texas Instruments targets bootstrap

Contents

Introduction

The boot sequence for each target is implemented in the xdc runtime support package named by the target; see xdc.bld.ITarget.rts. This package contains both a compiled version of the xdc.runtime package's modules and any necessary bootstrap code.

The xdc runtime support package and the TI C Compiler RTS Library are not the same. The TI C Compiler RTS Library contains an implementation of the C Standard Library as required by the ANSI C Language. The xdc runtime support package contains bootstrap code and pre-compiled versions of the modules contained in the xdc.runtime package. In some cases, the xdc.runtime package's modules call functions specified by the ANSI C Language which, for TI targets, is provided in the TI C Compiler RTS Library.

In the sections that follow, we outline in detail the initialization process common to all TI targets. This initialization process unfolds as follows:

  1. Initialize Registers - initialize processor-specific registers to enable a minimal C environment necessary for subsequent initialization
  2. User Reset Function - call user supplied reset function
  3. Process .cinit Records - initialize statically initialized C data
  4. Start Modules - run module-specific startup functions
  5. Process .pinit Records - run any C++ initialization functions; e.g., constructors for statically defined objects.
  6. Main() Function - call user defined main().

Initialize Registers

Execution on TI targets always starts at _c_int00, which is plugged as the reset vector. The boot sequence begins with the initialization of a few critical registers, including the system stack pointer. This part of the sequence is target-specific.

For a detailed view of the initial register setup, the actual boot code is available in the XDCtools installation. On all targets, the relevant portion of the boot code (in terms of the initial register setup) occurs between _c_int00 (where execution starts) and the call to the xdc_runtime_Startup_reset() function. Boot code for any other targets should be available in a similar location, inside the "rts" folder for that target.

The following sections show what register initialization occurs for each target and where the actual boot code is located:

C6000

  • Clear the IER and IFR.
  • Set the system stack pointer (B15) to point to the end of the stack section.
  • Set the global page pointer (B14) to point to the beginning of the .bss section.
  • On C6700 class processors, also set the floating point registers.

The c6000 boot code is available in boot.c contained in the ti.targets.rts6000 package The auto_init() function is defined in autoinit.c in the same package.

C2000

Set up the stack, initialize any status bits not initialized by the reset, and set the C28x modes. The c2000 boot code is available in the boot_cg.asm file contained in the ti.targets.rts2800 package.

ARM

Set user mode, change to 16-bit state, and initialize and align the user mode stack.

The arm7 (arm9) boot code is available in the boot.asm file contained in the ti.targets.arm.rtsarm7 and ti.targets.arm.rtsarm9 packages.

User Reset Function

The reset function is the first control point in the boot sequence. It occurs almost immediately after the target has been reset. The user-specified reset function is called after the initial register initialization, but before even the .cinit records have been processed. Any code that needs to be executed immediately after a reset, such as configuring or disabling a watchdog timer, should occur here.

The Startup module has a module-wide configuration parameter called resetFxn, which specifies the function to run at this point. The following example XDCscript configuration script demonstrates the Startup module's use:

 
 
var Startup = xdc.useModule('xdc.runtime.Startup');
Startup.resetFxn = "&myResetFxn";

Note that the "&" isn't actually being used as an operator in these statements; it's just part of a string. Internally, XDCscript knows to interpret the characters after the & as the name of an external user-supplied function.

The resetFxn is called before the .cinit records have been processed, so no data structures or variables have been loaded with their initial values at this point.

Process .cinit Records

For each statically initialized variable, TI targets generate a ".cinit record" that contains the location of the variable in memory and its initial value. These records are gathered together (in no particular order) to form a special .cinit output section that is part of the resulting object file. This section may be loaded onto the target and processed during the target's bootstrap or it may be read and processed directly by the application's loader. The choice between these two options is controlled by the -r option passed to the TI linker.

If the .cinit section is processed by the target's bootstrap, it occurs after the resetFxn and before any modules are initialized. So, module startup functions may assume that the C environment has been fully initialized but the resetFxn cannot.

Start Modules

At this point, the boot sequence calls the xdc_runtime_Startup_exec() function. This function then calls all the module startup functions (Mod_Module_startup) for each module Mod that was declared as "used" during the configuration process. The Startup module has two module-wide configuration parameters: firstFxns and lastFxns, which are arrays of user-specified functions to be called before and after the module startup functions, respectively.

The following example XDCscript configuration statements specify functions to be called with the firstFxns and lastFxns parameters.

 
 
 
 
 
 
 
var Startup = xdc.useModule('xdc.runtime.Startup');
var len = Startup.firstFxns.length;
Startup.firstFxns.length++;
Startup.firstFxns[len] = '&myFirst';
var len = Startup.lastFxns.length;
Startup.lastFxns.length++;
Startup.lastFxns[len] = '&myLast';

Functions added to "firstFxns" typically initialize values needed by module startup functions—such as initialization of global data used by modules, which is a function of platform-specific registers. Functions added to the "lastFxns" array might be used by middleware or other modules to perform any necessary initialization before main().

Process .pinit Records

After the module startup functions have run, the .pinit records are processed. The .pinit table consists of pointers to initialization functions. For C++ programs, class constructors of global objects execute during .pinit processing.

Note that the module initialization in the previous section may occur in the middle of .pinit processing. So, C++ constructors that require the services of a module must explicitly call Startup_exec() prior to using any module.

Main() Function

Finally, the startup function call the main() function with an argument count and an array of argument strings. The argument strings are stored on the target and initialized by the user's loader.

[printable version]  offline version generated on 18-Nov-2017 00:11 UTC 
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Personal tools
package reference