Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

C6RunLib Documentation

From Texas Instruments Wiki
Jump to: navigation, search

END OF LIFE

C6Run is still available for download, but is no longer being actively developed or maintained. Please consider other alternatives such as, Codec Engine IUNIVERSAL support, OpenCL or RCM.

^ Up to main C6EZRun Main Page ^

This article is part of a collection of articles describing the C6EZRun Software Development Project. Select the link above to return to the main project page.

Overview

C6RunLib works to build a static ARM library from C source files that can be linked with an ARM application and provide access to the DSP when library functions are called. This allows the user to keep portions of the application on the ARM and move other portions to the DSP.

The C6RunLib front-end consists of two scripts, c6runlib-cc and c6runlib-ar. The c6runlib-cc tool is used to compile C code to C6000 DSP object files. The c6runlib-ar tool is a specialized archiver that takes the DSP object files produced by the c6runlib-cc tool and generates an ARM side library. This output library can then be linked the ARM application to provide mostly transparent access to the DSP via the unchanged library interfaces. The application can be run from the ARM/Linux command-line as a native ARM application. Underneath the covers, however, the DSP is initiated, loaded with program code (which consists of the library functions), and runs waiting for function calls to arrive from the ARM application. All C I/O operations (printf, scanf, fopen, etc.) are routed to the ARM environment and console.


Examples: Building Code on the Host

The C6RunLib front-end scripts must be used together to create a library that can be linked with an ARM application. The c6runlib-cc script can be used as GCC would be used for compiling C code into object files. The c6runlib-ar script is used to take the object file output from c6runlib-cc and generate a library archive, similar to the ar tool of the GNU binutils. It is important to note that the c6runlib-ar tool expects to find all three outputs of the c6runlib-cc tool in the same location in the filesystem. You should not rename or move the object files generated by the c6runlib-cc tool, unless you rename or move all three outputs in the same way. See above for a description of the outputs from the c6runlib-cc script.

Here are some examples usages.

  • Compile a single C source file to an library file:
    [host]$ c6runlib-cc -c -o libfxns.o libfxns.c
    The output of the c6runlib-cc call is three files:
    1. the DSP object file, libfxns.o
    2. the ARM stub object file, libfxns.arm_stub.o
    3. and the function name list, libfxns.fxn_list.txt.
  • Archive a single object file into a library file:
    [host]$ c6runlib-ar rcs libfxns.lib libfxns.o
    The output of the c6runlib-ar call is a library archive called libfxns.lib.
  • Generating a complete ARM executable using a C6RunLib library file:
    [host]$ arm-none-linux-gnueabi-gcc -c -o main.o main.c

    [host]$ arm-none-linux-gnueabi-gcc -lpthread -o program.out main.o libfxns.lib
    The output is an ARM executable, program.out. Any function calls made in main.c to functions defined in libfxns.c will be executed by the DSP of the target platform.

C6RunLib Front-end Tool Usage

c6runlib-cc

The c6runlib-cc tool is a Bash shell script, intended to be run on a host Linux PC. The tool is used to compile C code and generate a C6000 object file. It does this by calling the TI C6000 compiler tool with appropriate command-line options. The command-line syntax of the c6runlib-cc tool matches (to the extent possible) the syntax used by the open source GCC compiler.

The c6runlib-cc tool currently only supports C source files. The source files compiled and assembled by c6runlib-cc are analyzed and used to produce two additional source files. These are remote-procedure call stubs, one for the ARM side and one for the DSP side. These files are also compiled to object file format by the c6runlib-cc script and are output to the same output directory specified for the main output object file. These object files are the same name as the specified output object file but with ".gpp_stub.o" and ".dsp_stub.o" extensions, respectively.

The c6runlib-cc tool does not support linking (as opposed to the GCC compiler). The outputs of the c6runlib-cc tool are intended to be fed to the c6runlib-ar archiver tool.

For reference, a list of GCC options can be found here

Usage summary

c6runlib-cc [options] files ...

Common Command-line Options

Option Meaning
-c Compile or assemble the source files, but do not link
-o file Place output in file file
-S Stop after the stage of compilation proper; do not assemble.
-E Stop after the preprocessing stage.
--help Print (on the standard output) a description of the command line options understood by c6runlib-cc
-O0 Reduce compilation time and make debugging produce the expected results (default).
-O1 Optimize
-O2 Optimize even more
-O3 Optimize yet more
-Idir Add the directory dir to the head of the list of directories to be searched for header files.
-iquotedir Same as -I.
-D name Predefine name as a macro, with definition 1.
-D name=definition The contents of definition are tokenized and processed as if they appeared during translation phase three in a `#define' directive. In particular, the definition will be truncated by embedded newline characters.
-U name Cancel any previous definition of name, either built in or provided with a -D option.
-include file Process file as if #include "file" appeared as the first line of the primary source file.
-Wall Enable common warning messages with verbose output
-w Inhibit all warning messages.

Ignored Command-line Options

All GCC options not specified above are ignored.

C6RunLib Specific Command-line Options

All C6EZRun specific options (i.e., ones not GCC-like and ones not intended to be passed to the TI compiler) are of the form "--C6Run:<option>". The following table gives all supported options of this form and what they are used for.

Option Meaning
--C6Run:debug Use debug mode libraries, also retains intermediate stub C files
--C6Run:release Use release mode libraries (default)

TI cl6x Command-line Options

Any option not interpreted as a GCC-like option (specified in the previous sections) or a C6EZRun-specific option is passed directly to the TI cl6x compiler. In most cases you should use the long form of the cl6x options to avoid any possible conflict with the GCC-like options that the script would interpret instead.

Refer to the "Optimizing Compiler User's Guide" that comes with your particular code generation tools release for all supported options (see here for an example).

One option that is known not to work is the -pm (program level compilation) option. Because this option combines all source files together for compilation, it breaks the C source file analysis, which is expected to done on a file-by-file basis.


c6runlib-ar

The c6runlib-ar tool is also a Bash shell script, intended to be run on a host Linux PC. It is used to create an ARM/Linux static library that can be linked into an application. To do this, the script calls the TI cl6x compiler/linker, the ARM GCC compiler, and the ARM GNU archiver as needed.

The c6runlib-ar tool relies on all the files output from the c6runlib-cc tool to be in the same path in the filesystem, which is how they are generated by the c6runlib-cc tool. The archiver tool then uses the cl6x tool to link and build the DSP executable image, including all the the object files given on the command-line and the corresponding DSP-side stub objects. The DSP executable is analyzed and the symbol addresses for the library functions are extracted and used to generate object files with absolute symbol references for the ARM-side application. The ARM side remote procedure call stub functions compiled by the c6runlib-cc tool rely on these absolute symbol references to get the function addresses at link time of the ARM application. Next the c6runlib-ar tool will convert the DSP executable image into a constant array in a C header file which is included in the main c6runlib task function. That task function is compiled using the ARM cross-compiler to generate an object file. Finally, the c6runlib-ar tool will generate a library archive consisting of the ARM-side remote procedure call stubs, the function address symbols, the various backend components (DSPLink, CMEM) and the C6RunLib task function (which has the DSP executable embedded as an array of const data).

Usage summary

c6runlib-ar [-]{dpqrtx}[cfosSuvV] [--C6Run:<options>] archive-file file...

Common Command-line Options

The only currently supported archiver command is -r, used to "replace existing or insert new file(s) into the archive". Typical usage is
c6runlib-ar rcs archive.lib <object file list>

C6RunLib Specific Command-line Options

All C6EZRun specific options (i.e., ones not GCC-like and ones not intended to be passed to the TI compiler) are of the form "--C6Run:<option>". The following table gives all supported options of this form and what they are used for.

Option Meaning
--C6Run:replace_malloc Replace all standard C malloc APIs with versions that allocate from the shared CMEM heap
--C6Run:no_replace_malloc Do not replace malloc APIs (default)
--C6Run:debug Use debug mode libraries
--C6Run:release Use release mode libraries (default)
--C6Run:save_dsp_image Save the embedded DSP executable image and memory map file (to use for debugging).


Buffer Passing using C6RunLib

Buffers that are passed from the ARM core to be used by the DSP core must be allocated as physically contiguous blocks. The mechanism to do this is by using the contiguous memory manager called CMEM. The C6EZRun framework allocates the entire CMEM region at once when the first buffer is requested from the framework. This physically contiguous heap memory is then managed in user space on the ARM side, avoiding costly user- to kernel-space transitions for every buffer allocation.

Buffer Allocation

Buffer allocation on the ARM-side within a C6RunLib application can be done with the following APIs

API Definition Usage Description
void *C6RUN_MEM_malloc(size_t); Memory allocation as described here.
void *C6RUN_MEM_calloc(size_t nelem, size_t elsize); Memory allocation with clear as described here.
void *C6RUN_MEM_realloc(void *oldPtr,size_t size); Memory reallocation as described here.
void *C6RUN_MEM_memalign(size_t alignment, size_t size); Memory allocation with alignment to the specified value.
void C6RUN_MEM_free(void* ptr); Free memory allocated by the C6RUN_MEM allocation routines.

All memory allocations are minimally aligned to 8 bytes. There is no header file provided to use these function. You should use the following extern definitions in the source files requiring the usage of these APIs (or create your own header file with these definitions):

// Prevent C++ name mangling
#ifdef __cplusplus
extern "C" {
#endif
  extern void    *C6RUN_MEM_malloc(size_t size);
  extern void    *C6RUN_MEM_calloc(size_t nelem, size_t elsize);
  extern void    *C6RUN_MEM_realloc(void *oldPtr,size_t size);
  extern void    *C6RUN_MEM_memalign(size_t alignment, size_t size);
  extern void     C6RUN_MEM_free(void* ptr);
// Prevent C++ name mangling
#ifdef __cplusplus
}
#endif

Note that these functions are coming from a C library, so they must be surrounded with the extern "C" statements when used in C++ files. The shown usage above will work for both C and C++ files.

As an alternative to using the C6RUN_MEM allocation and free APIs, the --C6Run:replace_malloc option can be used when calling c6runlib-ar to create a static library. This will replace all memory allocation and free calls in the ARM-side of the application. See c6runlib-ar options. The advantage of this is that the application code will not have to be modified to allocate buffers that can be shared with the DSP. But since all low-level memory routines are replaced, its possible this will cause issues with other aspects of the program, so this option is not enabled by default. When enabled, the following standard APIs are replaced: malloc, calloc, realloc, memalign, and free (corresponding one-to-one to the C6RUN_MEM APIs given above).

Modifying Function Signatures For Cache Optimizations

By default, buffers (pointers) that are passed as arguments to functions that are compiled to execute on the DSP are considered to be input/output buffers. This is the safe assumption to make if there is no information given about whether the pointer is being used to receive data into the function, transmit data out of the function, or both. By assuming that the buffer is input/output, all potentially required cache operations will be executed. For input buffers, the required operations are:

  1. Buffer cache writeback on the ARM before sending function execute message to the DSP
  2. Buffer cache invalidate on the DSP before function execution

For output buffers, the required operations are:

  1. Buffer cache writeback on the DSP after function execution
  2. Buffer cache invalidate on the ARM after receiving a function return message from the DSP

When buffers are both input and output buffers, both sets of operations must be performed.

Instead of assuming that a buffer/pointer parameter is an input/output buffer, it would be better to indicate what type of buffer the parameter is. This will allow the program to avoid cache operations when they are not required. To accomplish this, the C code can be marked up with the following case-sensitive keywords:

Buffer Type Keyword Usage Description
INBUF Indicates that this buffer requires input cache operations only.
OUTBUF Indicates that this buffer requires output cache operations only.
INOUTBUF Indicates that this buffer requires both input and output cache operations.
NONE Indicates that this buffer requires no cache operations (e.g. a hardware register address).

This keyword must be present at the beginning of the argument declaration in the function declaration of the C source file itself. This keyword technique is implemented using empty preprocessor macros, so the user should not define any macros with these same names. For example, consider a function with the following definition

void fxn1(void *inbuffer, void *outbuffer){ ... }

To optimize the cache operations required for calling this function, the function definition should be modified as follows

void fxn1(INBUF void *inbuffer, OUTBUF void *outbuffer){ ... }

Misapplication of these keywords will almost certainly cause unexpected results, so care must be taken.


Manual Cache Control

When buffers are specified as INOUTBUF, INBUF, or OUTBUF the C6EZRun framework will try to manage the needed cache operations automatically, for each buffer argument. When a buffer is specified as NONE, no cache operations will be attempted. These cache operations can be initiated and carried out manually in the caller and/or callee. One compelling reason to perform these operations manually, is that many individual buffer operations can be replaced by a single global cache operation. This has the potential to be faster than individual cache operations, especially when the buffer sizes are large.

The APIs available for manual cache management are the same for code running on the DSP and code running on the GPP. To build code using these APIs, you can either #include the "c6run.h" header file (located in <C6RUN_INSTALL_DIR/include) or you can use the following extern definitions in the source files requiring the usage of these APIs:

  extern void     C6RUN_CACHE_globalInv( void );
  extern void     C6RUN_CACHE_globalWb( void );
  extern void     C6RUN_CACHE_globalWbInv( void );
  extern void     C6RUN_CACHE_inv(void *ptr,size_t size);
  extern void     C6RUN_CACHE_wb(void *ptr,size_t size);
  extern void     C6RUN_CACHE_wbInv(void *ptr,size_t size);

The global invalidate and write back APIs (C6RUN_MEM_globalInv, C6RUN_MEM_globalWb and C6RUN_CACHE_globalWbInv) will cause the entire shared, contiguous memory regions to be affected (for the local core running the API). The local invalidate and writeback APIs (C6RUN_MEM_inv and C6RUN_MEM_wb, respectively) will only affect the region specified by the base pointer argument (ptr) and the buffer size argument. No validation that the specified range corresponds to an actual allocated buffer is performed.

To maintain data coherency across cores, the same cache management procedures must be performed, in the right order, as those the framework would typically do (see section above).


Multi-threaded Support and Asynchronous Function Calling (v0.98 or higher)

Starting with v0.98 of the C6EZRun package, the C6RunLib tools offer support for asynchronous function calls. Every function that is analyzed for remoting to the DSP is also used to create asynchronous support functions. A function of the form:

      <FxnReturnType> <FxnName> ( <FxnArguments> );

will cause the generation of the following three functions:

      C6RUN_RPC_AsyncHandle <FxnName>_asyncBegin    ( <FxnArguments> );
      bool                  <FxnName>_asyncIsDone   ( C6RUN_RPC_AsyncHandle );
      <FxnReturnType>       <FxnName>_asyncEnd      ( C6RUN_RPC_AsyncHandle );

These can be used to allow the calling thread to do work while waiting for the DSP to finish the actual function execution. To use these functions in the user's ARM application, they must be declared as extern in the C file in which they are called, or the user must create their own header file that declares these function prototypes. In other words, no header file is automatically generated. The C6RUN_RPC_AsyncHandle type is declared in the c6run.h header file (located in <C6RUN_INSTALL_DIR/include), so this header file must be included when making asynchronous calls.

In addition, the support for calling the DSP from multiple threads on the host ARM processor has been improved. Up to 256 function calls can be in-flight (called and running) between the ARM and the DSP. Each function call made to the DSP will run in its own task (thread) under the BIOS operating system.


Return to C6EZRun Main page

^ Up to main C6EZRun Main Page ^

This article is part of a collection of articles describing the C6EZRun Software Development Project. Select the link above to return to the main project page.