Overview of xdc.runtime/Example 2

From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  offline version generated on 24-Feb-2019 01:02 UTC 

Overview of xdc.runtime/Example 2

Embedded use of xdc.runtime

Contents

Minimizing External Dependencies

The xdc.runtime package's modules are designed to be used in environments where only a minimal subset of the ANSI C Standard Library is available. At the same time, these modules can be easily used in environments where you want them to use existing Standard Library support; e.g., using malloc() and free() for memory allocation and fwrite() for character I/O. In order to support both use cases, the xdc.runtime modules define several configuration parameters that allow the user to precisely control how much of the ANSI C Standard Library is required by the xdc.runtime package.

In this example we show how to configure the xdc.runtime packages to minimize references to the ANSI C Standard Library. The xdc.runtime package optionally uses the ANSI C Standard Library to allocate memory, perform character I/O, and perform application shutdown. Since the Memory module handles all memory management and the System module is responsible for all character I/O and application shutdown, we need to configure the Memory and System modules to minimize their references to the ANSI C Standard Library.

Configuring the Memory Module

All memory allocation within the xdc.runtime package is handled via calls to Memory_alloc() or Memory_calloc(). Both methods take a heap parameter from which the memory is allocated and this heap parameter is either NULL, indicating that Memory should use the configured "default heap", or it is a non-NULL instance pointer created by some heap module. The Memory module itself does not reference any memory allocation functions from the ANSI C Standard Library, any such references are made indirectly via the specified heap instance. So, to eliminate all references to malloc() and free(), it is sufficient to ensure that all heaps instances come from modules that do not reference malloc() or free().

The xdc.runtime package contains two heap managers: HeapMin and HeapStd. The HeapStd module uses malloc() and free(). However, HeapMin simply manages a "high water" mark within a pre-configured static buffer. As a result, HeapMin can be used in applications that do not need dynamic memory management to eliminate references to malloc() and free().

By default, the Memory module uses HeapStd as the "default heap" when NULL is passed as the first parameter to Memory_alloc() or Memory_calloc(). Fortunately the Memory module provides a configuration parameter, Memory.defaultHeapInstance, that allows you to specify an alternative default heap.

 
 
 
var HeapMin = xdc.useModule("xdc.runtime.HeapMin");
var Memory = xdc.useModule("xdc.runtime.Memory");
Memory.defaultHeapInstance = HeapMin.create({size: 4096});

Of course some environments without malloc() and free() still need dynamic memory management. In this case, you will have to create your own module that implements the IHeap interface. For more information about how to create custom heap mangers see Extending xdc.runtime Memory.

Configuring the System Module

The System module is responsible for basic character output and application termination. In order to enable System to operate in different environments with a variety of character output options, System relies on a "provider" module that implements the ISystemProvider interface. The System module provides a configuration parameter, System.SupportProxy, which determines the "provider" module used.

The xdc.runtime package contains two system providers: SysMin and SysStd. The SysStd module uses putchar() and fflush() for basic character output. However, SysMin simply copies characters to a pre-configured static buffer for character output and provides a configuration parameter that allows you to specify how these characters are output when System_flush() is called. As a result, SysMin can be used in applications that need to avoid all references to the ANSI C Standard Library I/O functions.

With the exception of exit(), atexit(), and abort(), the System module does not directly reference any ANSI C Standard Library functions; any other references are the result of the System module's supporting module System.SupportProxy. If the System.SupportProxy configuration parameter is not set, it defaults to SysMin.

By default, the SysMin support module will call fwrite() to output characters written to its internal buffer. To eliminate this reference, it is sufficient to define your own output function, say myOutputFxn, and set SysMin.outputFxn to reference this function.

 
 
 
 
var System = xdc.useModule("xdc.runtime.System");
var SysMin = xdc.useModule("xdc.runtime.SysMin");
SysMin.outputFxn = "&myOutputFxn";
System.SupportProxy = SysMin;  /* not really necessary since this is the default */

Of course there may be other reasons why the use of SysMin is not appropriate. For example, you may want to output characters at the time they are generated rather than buffering them. In this case, you'll need to create your own ISystemProvider module. For information about how to create a new ISystemProvider module see Extending xdc.runtime System.

A Complete Example

Combining the configuration options illustrated above, we can create a configuration of the xdc.runtime package that has no external references to the ANSI C Standard Library functions other than exit(), atexit(), and abort().

app.c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#include <xdc/std.h>
 
#include <xdc/runtime/System.h>
#include <xdc/runtime/Memory.h>
 
#include <string.h>
 
/* ======== main ======== */
Int main(Int argc, String argv[])
{
    Int i;
    Char *buf;
 
    buf = Memory_calloc(NULL, 80, 0, NULL);
    strcat(buf, "hello world");
 
    for (i = 0; i < 3; i++) {
        System_printf("%s: %d\n", buf, i);
    }
 
    return (0);
}
 
/* ======== myOutputFxn ======== */
Void myOutputFxn(Char *buf, Int len)
{
    /* output len chars from the buffer buf */
        :
}
app.cfg
 
 
 
 
 
 
 
 
 
 
 
 
 
var System = xdc.useModule("xdc.runtime.System");
var Memory = xdc.useModule("xdc.runtime.Memory");
 
/*  eliminate all references to stdio (except exit,
 *  abort, and atexit) 
 */
var SysMin = xdc.useModule("xdc.runtime.SysMin");
SysMin.outputFxn = "&myOutputFxn";
System.SupportProxy = SysMin;
 
/* ensure all memory manager references go to HeapMin */
var HeapMin = xdc.useModule("xdc.runtime.HeapMin");
Memory.defaultHeapInstance = HeapMin.create({size: 4096});

Notice that the only differences between this example and Runtime Example 1 is the addition of the output function, myOutputFxn, and straightforward changes to the application's configuration script. This illustrates one of the key benefits of the xdc.runtime package: code that only references the services provided by the xdc.runtime package is 100% reusable among platforms ranging all the way from native workstations down to highly resource constrained embedded platforms.

While it is technically possible to possible to make the same claim about the ANSI C Standard Library, the code size footprint, execution time overhead, and inflexibility of this library make it impractical in many embedded environments. As a result, embedded programmers have learned to avoid using the the ANSI C Standard Library in any code targeted for deployment in resource constrained devices, in effect requiring two distinct code bases: code for initial development and code for deployment. The xdc.runtime package allows you work with and reuse a single code base for any platform.

See also

Overview of xdc.runtime/Example 1 Using xdc.runtime in native host applications

[printable version]  offline version generated on 24-Feb-2019 01:02 UTC 
Copyright © 2008 The Eclipse Foundation. All Rights Reserved
Personal tools
package reference