From RTSC-Pedia

Jump to: navigation, search
revision tip
—— LANDSCAPE orientation
[printable version]  offline version generated on 04-Aug-2010 21:08 UTC

ROV Module Writers Guide/Module Writer FAQ

Discussion of specific ROV tasks and use cases

This section of the guide deals with specific ROV use cases. It is organized like a FAQ in question and answer form with code snippets and discussion of the answers.

Contents

How do I incorporate the data from my 'Basic' view into my 'Detailed' view?

With the tab support in ROV, the convention for the relationship between a 'Basic' and a 'Detailed' view is that the Detailed view displays all of the same fields as the Basic view, but with a few extra fields which require extra processing.

To avoid duplicating all of the processing for your basic view, simply call your 'viewInitBasic' function from your 'viewInitDetailed' function.

Module.xdc
 
 
 
 
 
 
 
 
 
 
 
 
metaonly struct BasicView {
    String  label;
    Int     fldA;
    Int     fldB;    
}
 
metaonly struct DetailedView {
    String  label;
    Int     fldA;
    Int     fldB;
    Int     fldC;    
}
Module.xs
 
 
 
 
 
 
 
function viewInitDetailed(view, obj) 
{
    // Call the basic view function first
    viewInitBasic(view, obj);
 
    // Fill in the other fields
}

This will potentially result in the same view code being run twice. For example, if the user clicks on the 'Basic' tab and then clicks on the 'Detailed' tab, the 'Basic' view function will be run twice. The penalty is usually minor, though, since the target state has already been read in.

If I have a Handle to an instance, how do I retrieve the view for that instance?

If a state object contains a handle to an instance of another module, the view for that handle can be retrieved using Program.scanHandleView.

Module.xdc
 
 
 
 
 
 
 
Instance_View {
    String taskLabel;
}
 
Instance_State {
    Task.Handle tsk;
}
Module.xs
 
 
 
 
 
 
 
 
 
 
 
 
function viewInitBasic (view, obj)
{
    try {
        var tskView = Program.scanHandleView('Task', obj.tsk, 'Basic');
    }
    catch (e) {
        Program.displayError(view, "taskLabel", e);
        return;
    }
 
    view.taskLabel = tskView.label;
}

How do I retrieve a view from another module if I don't have a Handle?

To retrieve a view of another module, you just need the module name and the name of the view that you want to retrieve. Use Program.scanModuleView if the view is a module-type view, and use Program.scanInstanceView if the view is an instance-type view. Program.scanModuleView will return just the requested module view. Program.scanInstanceView will return an array of instance views, one for each instance of the module.

Module.xs
 
 
 
 
 
 
 
 
 
 
 
try {
    var semViews = Program.scanInstanceView('Semaphore', 'Basic');
}
catch (e) {
    Program.displayError(view, "blockedOn", e);
    return;
}
 
for each (var semView in semViews) {
    // Do something with the Semaphore's view data
}

How do I retrieve the raw state data for a module?

To retrieve just the state data for another module, and not its processed view data, you can use the Program.scanRawView API. This returns a structure of type xdc.rov.Program.RawView, which contains the module state, an array of all the instance states, and an object containing all of the module's configuration info.

The use of this API is discouraged unless there is no other way to retrieve the desired data. The problem with using it is that the raw data has not been validated by the module's own view, and so you may end up operating with corrupted data.

Module.xs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
try {
    var rawView = Program.scanRawView('Task');
}
catch (e) {
    Program.displayError(view, "someField", e);
    return;
}
 
// Do something with the module state
var curTask = rawView.modState.curTask;
for each (var instState in rawView.instStates) {
    // Do something with the instance states
}
 
// Do something with the module config info
var numPriorities = rawView.modCfg.numPriorities;

The scanRawView API can also be used as a way for an instance view to retrieve the raw module state, but again it is preferable to retrieve a formal Module view so that it includes some data validation.

How do I retrieve the view for an embedded instance (advanced)?

If a state object contains an embedded instance of another module, a view for that embedded instance can be retrieved using Program.scanObjectView.

Module.xs
 
 
 
 
 
 
 
 
 
 
try {
    var qView = Program.scanObjectView('ti.sysbios.misc.Queue', obj.pendQ, 'Basic');
}
catch (e) {
    Program.displayError(view, "pendQ", e);
    return;
}
 
// Do something with the view
var elem = qView.elem;

Since XDCtools has no way of knowing what embedded objects are present in a system, embedded objects do not appear in the list of a module's instances until they have been scanned in this way.

How do I fetch a structure for which I have an address?

The Program.fetchStruct API is used to retrieve and decode a structure from the target given its address. It takes a fetch descriptor and the address of the structure to fetch. Fetch descriptors are explained here.

The fetchStruct API returns a JavaScript object representing the structure with the data from the target.

Module.xs
 
 
 
 
 
 
 
 
 
 
try {
    var myStruct = Program.fetchStruct(obj.structPtr$fetchDesc, obj.structPtr);
}
catch (e) {
    Program.displayError(view, "pendElems", e);
    return;
}
 
// Do something with the fetched struct
view.fieldA = myStruct.fieldA;

I have a pointer to a structure, but the pointer is not part of my state. How do I fetch the structure?

It is possible to have a pointer that is not a part of your state structure, or that actually has a different type then what is specified in the state structure. For example, if you traverse a linked list of data, the type of the element pointers may be different than the type of data on the list.

In this case, you will not have a '$fetchDesc' property generated in your object for the type of data you are interested in. It is still possible to fetch this data, however.

For every type that a module defines, a '$fetchDesc' property is defined for that type. For example, if the Semaphore module defines a struct PendElem, then the Semaphore module will have a property 'Semaphore.PendElem$fetchDesc'.

Module.xs
 
 
 
 
 
 
 
 
 
 
 
var Semaphore = xdc.useModule('Semaphore');
 
try {
    var pendElem = Program.fetchStruct(Semaphore.PendElem$fetchDesc, pendElemAddr);
}
catch (e) {
    Program.displayError(view, "pendElems", e);
    return;
}
 
// Do something with the fetched struct (pendElem)

My state structure contains an array. How do I fetch the array's data?

The Program.fetchArray API is used to retrieve an array from the target given its address and length. It takes a fetch descriptor, the address of the array, and the length of the array.

The fetchArray API returns a JavaScript array containing the data from the target.

Module.xdc
 
 
 
struct Instance_State {
    Char stack[];
};
Module.xs
 
var data = Program.fetchArray(obj.stack$fetchDesc, obj.stack, obj.stackSize);

If the array contains structures, those structures will be decoded. However, if the array contains pointers, the data at those pointers will have to be fetched separately.

How do I fetch a string?

If your state structure contains a string, the field will simply contain the address of the string, and not the string of characters. To retrieve the string itself, use the Program.fetchString API, passing it just the address of the string.

Module.xs
 
 
 
 
 
 
try {
    view.myString = Program.fetchString(obj.myString);
}
catch (e) {
    Program.displayError(view, "myString", e);
}

ROV retrieves the string by reading characters starting at the given address until it finds the terminating character '\0'. To protect against memory corruption, ROV will read a maximum of 128 characters and throw an error if this limit is reached.

How do I fetch a global scalar value?

If you have an address and want to retrieve a global scalar, you will need to use the xdc.rov.support.ScalarStructs module. This module simply defines a structure for every XDC scalar type. The structures are named after the scalar, such as ScalarStructs.S_UInt. The structures contain a single field with the name 'elem' which is of the type of the scalar.

ScalarStructs.xdc
 
 
 
struct S_UInt {
    UInt elem;
};

To retrieve the scalar, use the fetch descriptor from the ScalarStructs module for the structure corresponding to your scalar. For example, to retrieve a UInt32, use ScalarStructs.S_UInt32$fetchDesc.

Pass this fetch descriptor to the Program.fetchStruct API, and it will return a structure containing your scalar in the 'elem' field of the structure.

For example, to retrieve a UInt32 at the address 'addr':

 
 
 
 
 
 
 
 
var Program = xdc.useModule('xdc.rov.Program');
var ScalarStructs = xdc.useModule('xdc.rov.support.ScalarStructs');
 
/* Fetch the UInt32 at address 'addr' using the ScalarStructs module. */ 
var sstruct = Program.fetchStruct(ScalarStructs.S_UInt32$fetchDesc, addr);
 
/* fetchStruct will return a structure with the value in the 'elem' field. */
var myInt = sstruct.elem;

How do I retrieve the label for my instance?

All instances have a label, which is stored in obj.$label. The label varies depending on whether or not a name was given to the instance by the user.

 
 
Task@c0000008// No name given
Task@c0000008:myTsk0// Named 'myTask0'

To retrieve just the given name of the instance, without the module name and address, use the Program.getShortName API:

Module.xs
 
view.label = Program.getShortName(obj.$label);

If a name was not given to the instance, Program.getShortName will return an empty string.

How do I access the module configuration values used to configure my application?

The module config values used to configure the application are available from within the view initialization functions. They can be accessed by calling Program.getModuleConfig(moduleName), which returns an object containing the configuration info.

In this example, the instance's priority is compared to the configured maximum priority to validate it.

Module.xs
 
 
 
 
 
 
 
 
 
 
 
view.priority = obj.priority;
 
/* 
 * Validate 'priority' by comparing the actual priority to the configured
 * maximum priority.
 */
var modCfg = Program.getModuleConfig('Task'); 
if (obj.priority > modCfg.numPriorities) {
    Program.displayError(view, "priority", "Corrupted data: Task priority is greater" +
                                           "than Task.numPriorities");
}

How can I save data to be shared across different views?

Some modules may contain data which is referenced by more than one of the module's views. ROV provides a mechanism for storing and sharing this data across the different views using the Program.getPrivateData API.

The 'getPrivateData' API takes a module name and returns a JavaScript object which can be used to store data. Data can be stored by hanging it off of this object.

ROV will refresh these objects at every breakpoint (whenever the ROV Model receives a 'clear cache' command).

Module.xs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
var Program = xdc.useModule('xdc.rov.Program');
 
/* Retrieve the private data object for this module. */
var modData = Program.getPrivateData('modA');
 
/* Check if the data has been retrieved yet. */
if (modData.myData === undefined) {
    /* 
     * Retrieve the data and store it in modData.myData so
     * that it can also be accessed by other views that need it.
     */
}
 
/* The data is available to work with. */

How do I retrieve the address of my state structure?

The 'obj' parameter to the view init functions has a '$addr' field which stores the address of the module or instance state structure. This is the same address displayed in the 'address' field of the GUI.

Module.xs
 
 
var address = obj.$addr
// Do something with the address

How do I lookup the symbols associated with an address?

If a state object contains a pointer which has a symbol, such as a function pointer, a reverse symbol lookup can be performed to retrieve the symbol name using the Program.lookupDataSymbol and Program.lookupFuncName functions. The 'lookupDataSymbol' function is used for symbols in data pages and the 'lookupFuncName' function is used for symbols in text pages.

Because there may be multiple symbols at a given address, each of these functions returns an array of symbols.

Module.xs
 
 
 
 
 
 
 
/* Get the name of the function at the address 'obj.fxn'. */
var symArr = Program.lookupFuncName(obj.fxn);
view.fxn = symArr;
 
/* Get the name of the symbol at the address 'obj.$addr'. */
symArr = Program.lookupDataSymbol(Number(obj.$addr));
view.stateName = symArr;

How do I display the names for an enum type instead of the integer values?

Enum values have a separate string and integer representation. Use String(enumValue) to force the string representation and Number(enumValue) to force the integer representation.

Module.xdc
 
 
 
 
 
 
 
 
enum Mode {
    Mode_COUNTING, 
    Mode_BINARY
};
 
struct Instance_State {
    Mode mode;
};
Module.xs
 
 
view.mode = String(obj.mode); // sets mode to "Semaphore.Mode_COUNTING"
view.mode = Number(obj.mode); // sets mode to "0"


Views
Personal tools
package reference