Working with xdc.runtime

From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  [offline version]offline version generated on 25-Oct-2014 02:10 UTC

Working with xdc.runtime

How to build xdc.runtime for your target and platform

Contents

Introduction

This section contains topics related to the "manipulation" and use of xdc.runtime package as a whole rather than individual modules within this package. For a basic overview of the xdc.runtime package see Overview of xdc.runtime.

Re-building xdc.runtime Support Packages

The xdc.runtime package contains 100% portable ANSI C sources but does not include any precompiled libraries of these sources. However, pre-built libraries are generally provided in separate packages named by the targets you're using; whenever you configure an application you must name a target and this target names a default package containing a pre-built library of the xdc.runtime sources. In most cases, the packages containing these pre-built libraries are sufficient and there is no need to rebuild these packages. But, there are times when it's necessary:

  • if you are using a different version of the compiler originally used to build the library and your compiler is unable to use the previously built library; because of an incompatible object file format change, for example
  • if you need to use a new version of the xdc.runtime package

The remainder of this section describes how to rebuild packages containing pre-built libraries of the xdc.runtime sources using the xdc command. This command requires that you specify the targets you want to build for and the installation directory of the compiler tool chain to use for each target. If you haven't already done this, see the "Setup for xdc builds" section below for a simple example.

Re-building in-place

Re-building in-place.  The simplest way to rebuild any source package is to simply clean and rebuild from the package's base directory. In the example below, we assume that the package you need to re-build is named ti.targets.rts6000.

 
 
 
% cd .../packages/ti/targets/rts6000
% xdc clean
% xdc

You should see all of the modules in the xdc.runtime package being compiled and archived without any errors or warnings.

You should always maintain a backup copy of any package you modify. In the example above, the "xdc clean" operation may remove support for targets that you don't currently use but may want to use at a later date.

Re-building a local copy (recommended)

Re-building a local copy (recommended).  Most development groups prefer to keep all third-party packages unchanged from there original installation state. This makes it much easier to accept and use updates of these packages from the third-party. Fortunately, the package path allows you to easily "override" any existing package with a local version. As before, we assume that the package you need to re-build is named ti.targets.rts6000 but in this case we first need to create a copy of this package in a separate repository denoted by ".../local".

 
 
% mkdir -p .../local/ti/targets/rts6000
% cp -rp .../packages/ti/targets/rts6000 .../local/ti/targets/rts6000

We could have used xdc.tools.repoman or xdc.tools.repoman.sg to copy the ti.targets.rts6000 package, but we intentionally chose to use familiar file system commands to keep the process as transparent as possible. The repoman command to copy the package shown above is "xs xdc.tools.repoman -c -p .../packages -r .../local ti.targets.rts6000", where .../packages is the repository containing the ti.targets.rts6000 package.

Now that we have a local copy of the ti.targets.rts6000 package, the process to re-build is identical to the process shown to build the package in-place.

 
 
 
% cd .../local/ti/targets/rts6000
% xdc clean
% xdc

To use this newly re-built package in lieu of any existing version, simply place the ".../local" repository at the beginning of your package path.

Windows
 
% set XDCPATH=.../local
Unix
 
% export XDCPATH=.../local

For more information about managing the package path see Managing the Package Path.

Setup for xdc builds

Setup for xdc builds.  If you are not already using the xdc command to build source files, you'll have to create a file, named config.bld, that specifies what targets to use when building your sources and where you've installed the compilers that are required by these targets. This file can be placed in any directory named on the package path or in the package you want to (re)build.

The following example illustrates how to setup the xdc command to compile sources using the TI C6x compiler to build for the C64 Plus architecture. In this case, we assume the environment variable TI_DIR is defined to be the installation directory of TI's Code Composer product and that this directory contains an installation of the C6x compiler in the ./tools/compiler/c6000 sub-directory.

config.bld
 
 
 
 
 
 
 
 
/* specify the compiler installation directory for the targets we need */
var C64P = xdc.module("ti.targets.C64P");
var tools = java.lang.System.getenv("TI_DIR");
C64P.rootDir = tools + "/tools/compiler/c6000";
 
/* specify the target(s) to use when building source files */
var Build = xdc.module("xdc.bld.BuildEnvironment");
Build.targets = [C64P];         /* only build using C64P target */

For more information about how to leverage the xdc command to build using any C compiler tool chain, see Managing Compiler Toolchains.

Multi-Threading Support

In order to be portable to any multi-threaded runtime (e.g., SYS/BIOS or posix), the xdc.runtime modules protect their critical sections with the Gate_enterSystem() and Gate_leaveSystem() methods. These methods, in turn, use the mutex gate associated with the xdc.runtime.System module.

Some RTOS providers automatically configure the xdc.runtime.System gate to ensure correct operation in a multi-threaded environment. For example, if you use the ti.sysbios package, the following lines are automatically added to your configuration by the ti.sysbios package itself:

 
 
 
var System = xdc.useModule("xdc.runtime.System");
var GateHwi = xdc.useModule("ti.sysbios.gates.GateHwi");
System.common$.gate = GateHwi.create();

If the System gate is not configured by some package in the system, it will default to an instance of GateNull. Since GateNull provides no synchronization, it should only be used for modules that are never called by more than one thread at a time. Multi-threaded applications must either

  1. configure the System module's gate with a mutex that serializes all threads that access the xdc.runtime modules, or
  2. ensure that there are no concurrent accesses to the xdc.runtime modules

The table below summarizes the synchronization requirements for the xdc.runtime modules. Any modules not mentioned do not require synchronization.

Module Requires System gate?
Core yes, to maintain pre-module instance list. Only called during instance create and delete
Error yes, but only to detect errors that occur within error handlers. Error_print() is not protected by any gate and, as a result, concurrent calls to Error_print() will result in intermingled error output
System only System_atexit() and during application termination
Assert, Memory, Log, Diags, Text, Timestamp no
HeapMin, HeapStd, SysMin, LoggerBuf yes
SysStd no requires a thread-safe ANSI C Standard Runtime library
LoggerSys no requires that System_putch() be thread-safe
TimestampNull no

Porting to a New Target

Most users will never have to port the xdc.runtime package to a new target. If you are not adding a new target to the RTSC Build Model, you should skip this section.

Each target names a target-specific package that has already compiled the xdc.runtime modules into a library. Since targets can be added without requiring a re-release of the xdc.runtime package, the xdc.runtime package cannot contain any pre-built libraries. The xdc.runtime package's modules are provided in 100% portable C source form and each target names a target-specific package that contains pre-built libraries suitable for that target.

To create a package that contains pre-built versions of the modules in the xdc.runtime package you need to:

  1. create a new target for your compiler tool chain (say adi.targets.Blackfin) whose rts parameter names a package that will house a compiled version of the xdc.runtime modules (say adi.targets.rtsblackfin)
  2. create the adi.targets.rtsblackfin package; i.e., create a directory named adi/targets/rtsblackfin containing a package.xdc file similar to that shown below.
  3. add a package build script (package.bld similar to the one shown below) to build this package for the new target
  4. add the new target to your config.bld file and build adi.targets.rtsblackfin package by typing xdc in the package's base.

package.xdc

The package specification below both names the package, adi.targets.rtsblackfin, and provides a basic description of the package that will be displayed by the xdc.tools.cdoc.sg command.

 
 
 
 
 
 
 
/*!
 *  Pre-built xdc.runtime libraries for ADI blackfin targets
 *
 *  This package builds all xdc.runtime modules and provides all necessary 
 *  support for using the xdc.runtime package on ADI blackfin devices.
 */
package adi.targets.rtsblackfin {}

package.bld

The build script below builds the xdc.runtime modules in the package containing this script. This allows you to build and release support for new targets without ever having to modify the xdc.runtime package itself!

 
 
 
 
 
 
 
 
 
 
 
 
 
/* get build support from the xdc.runtime package itself */
var RtsBuild = xdc.loadCapsule("xdc/runtime/build.xs");
 
/* add makefile content from xdc.runtime to this package */
Pkg.makePrologue = RtsBuild.makePrologue; 
 
/* build libraries for all targets that support the "blackfin" ISA */
for (var i = 0; i < Build.targets.length; i++) {
    var targ = Build.targets[i];
    if (targ.isa == "blackfin") {
        Pkg.addLibrary("lib/" + Pkg.name, targ).addObjects(RtsBuild.objs);
    }
}

If the build of the package succeeded, you've completed the first test of your new target. To ensure that clients can use your target to create executables you should also build and run some simple client applications. This is described in the next section.

Testing Your New Target

To test your port of the xdc.runtime package you should be able build and run the examples referenced in the Overview of xdc.runtime. Since Example 2 minimizes external dependencies, starting with this example will allow you to focus on issues related to your target.

Removing xdc.runtime From an Application

Because the initialization of modules is controlled by the xdc.runtime.Startup module and most modules - even those without startup initialization requirements - rely on at least one of the xdc.runtime modules (e.g., xdc.runtime.Memory), the XDCtools implicitly import a package containing a pre-compiled version of the xdc.runtime modules. However, there are times when you may need to create an application that does not include any of the xdc.runtime code or when you need to specify a specific package of pre-compiled xdc.runtime modules.

Each RTSC target names a package containing pre-compiled versions of the xdc.runtime modules (see xdc.bld.ITargets.rts) and, by default, this package will be imported into your application's configuration. However, you can disable this implicit import by setting the rtsName attribute of the xdc.bld.Executable instance created for your application to null.

If you use the RTSC Build Engine to create your application, your package.bld build script will include a statement similar to the following:

 
var exe = Pkg.addExecutable("myApp", target, target.platform, {rtsName: null});

If you use the xdc.tools.configuro tool, your command line should include the -rtsName option to disable the inclusion of the target's package of pre-compiled xdc.runtime modules (or to specify an alternative package).

 
% xs xdc.tools.configuro ... -rtsName="" myApp.cfg

Using a Customized Build of xdc.runtime

Each RTSC target names a package containing pre-compiled versions of the xdc.runtime modules (see xdc.bld.ITargets.rts) and, by default, this package will be imported into your application's configuration. However, you can override this implicit import by setting the rtsName attribute of the xdc.bld.Executable instance created for your application to the name of any package that supplies pre-built versions of the xdc.runtime modules. You may want to do this to use different compiler optimization flags or use a more recent version of a compiler than that used by the package named by the target.

If you use the RTSC Build Engine to create your application, your package.bld build script will include a statement similar to the following:

 
var exe = Pkg.addExecutable("myApp", target, target.platform, {rtsName: "my.local.runtime"});

If you use the xdc.tools.configuro tool, your command line should include the -rtsName option to specify the package of pre-compiled xdc.runtime modules to use in lieu of the one named by the target.

 
% xs xdc.tools.configuro ... -rtsName="my.local.runtime" myApp.cfg

Using xdc.runtime Within C-Only Environments

The xdc.runtime package contains a single C++ file that is used to portably initialize all modules in a system by calling Startup_exec() as part of a static C++ initializer. However, there are execution environments where C++ is not supported; e.g., some micro-controllers are only supported by a C compiler, and some kernel-level execution environments don't support C++ initializers. In these cases, it is necessary to

  1. rebuild all of the xdc.runtime C sources without this one C++ file,
  2. configure your system to use this new variant of the runtime, and
  3. "manually" call Startup_exec() prior to using any xdc.runtime services.

If your target supports C++ and there is an existing runtime support library package for your target, you can skip the the first two steps above by simply defining a C function named __xdc__init() in the same file that calls Startup_exec(). The __xdc__init() symbol is referenced in all generated configuration files (to force the initialization of a C++ variable that in turn causes Startup_exec() to run). By defining this symbol in a file that is always linked ahead of any library, you can effectively "short-circuit" the C++ initializer defined in the xdc.runtime sources.

 
 
 
 
 
 
 
 
#include <xdc/runtime/Startup.h>
 
int __xdc__init(void) { return 0;}
 
int main(int argc, char *argv[]) {
   Startup_exec();
       :
}

Rebuilding Just the C Sources

To rebuild the xdc.runtime so that it does not include any C++ files, you can use a package.bld similar to the one shown below. The only difference between this file and the one shown in the section "Porting to a New Target" is that rather than using the RtsBuild.objs list of files (at line >), the package.bld below uses RtsBuild.c_objs (a list that includes all xdc.runtime sources except for the C++ initialization file).

package.bld
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
>
 
 
/*
 *  This build script builds xdc.runtime modules in the current package
 */
 
/* get build support from the xdc.runtime package itself */
var RtsBuild = xdc.loadCapsule("xdc/runtime/build.xs");
 
/* add makefile content from xdc.runtime to this package */
Pkg.makePrologue = RtsBuild.makePrologue; 
 
/* build libraries for all targets that support the "blackfin" ISA */
for (var i = 0; i < Build.targets.length; i++) {
    var targ = Build.targets[i];
    if (targ.isa == "blackfin") {
        /* add only C files: this requires all users to explicitly call Startup_exec() */
        Pkg.addLibrary("lib/" + Pkg.name, targ).addObjects(RtsBuild.c_objs);
    }
}

Use This New Build of xdc.runtime

To use this custom build of the xdc.runtime, we follow the same proceedure outlined in the section "Using a Customized Build of xdc.runtime"; i.e., either use the rtsName attribute of executables when using package.bld scripts or use the -rtsName command line option when using xdc.tools.configuro directly.

Manually Initializing All RTSC Modules

Before using any RTSC module, including any module in the xdc.runtime package, it must first be initialized. The initialization of all RTSC modules is normally handled automatically, but if you are using a variant of xdc.runtime that does not include any C++ initializers you must explicitly call Startup_exec() before the first use of any RTSC module. Normally this simply means calling Startup_exec() in main().

 
 
 
 
 
 
#include <xdc/runtime/Startup.h>
 
int main(int argc, char *argv[]) {
   Startup_exec();
       :
}
[printable version]  [offline version]offline version generated on 25-Oct-2014 02:10 UTC
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Personal tools
package reference