| Embedded IDE Link™ CC | ![]() |
Create MATLAB® software objects representing embedded data or functions in program on target
objname = createobj(cc,'symbolname');
objname = createobj(cc,'symbolname','option');
objname = createobj(cc,'functionname','function','funcdecl',...
'function_declaration_string);
objname = createobj(cc,functionname,'function','allocate',...
{'input',value1,'input2',value2,...});
objname = createobj(cc,'symbolname') makes an object in your MATLAB workspace named objname. Your new object contains information about the program symbol defined by symbolname. To use createobj successfully, you must have loaded a .out file to your target in CCS, and the symbol must be in the current symbol table in CCS.
symbolname can be any variable name or function name. By default, the embedded variable object returned accesses a variable within the current program scope.
Depending on the variable type and the storage used (register, memory, structure, function) for the variable, createobj generates an object that is one of the following kinds of objects:
Memory object — access any symbol that resides in DSP memory
Register object — access any symbols that reside in DSP registers
Structure object — container class that accesses any symbol stored as a C struct type or C union type
Function object — access any callable C function or assembly function that has a C prototype
You do not create memory objects directly. Rather, you use createobj to make objects that are derived classes of memory objects:
Numeric class objects — objects that access primitive data type variables, such as floats, ints, and shorts.
Numeric class objects also have derived classes:
Pointer class objects — objects that access pointer data types (unsigned integers)
Enum class objects — objects that access enumerated data types (integers)
String class objects — objects that access string data types (characters)
Bitfield class objects — objects that access bitfield data types
Like memory objects, you cannot instantiate a register object directly. Using createobj, you create a derived class object that accesses variables stored in registers on the processor.
Rnumeric class objects — objects that access primitive data type variables, such as floats, ints, and shorts
Rnumeric class objects have derived classes just like numeric objects:
Rpointer class objects — objects that access pointer data types (unsigned integers)
Renum class objects — objects that access enumerated data types (integers)
Rstring class objects — objects that access string data types (characters)
It should be clear that register objects differ from memory objects only in the kind of data storage they access — registers versus memory locations. Otherwise, many of the properties and methods of the two object classes are the same.
Acting as a container class, structure objects hold either memory objects or register objects, as defined in the descriptions of both objects. Unlike memory or register objects, you create structure objects directly when you use createobj to access a C struct or C union data type variable.
When you create an object that accesses a C function in your program, createobj returns a function object, whose properties and methods provide information about and the ability to manipulate the target function. Your target can be any function in your code, whether a library function, a subprogram in your code, or a function you create from the MATLAB command line.
Note When you use the function call capability with any C28x™ processor, you must disable the watchdog timer or the function call process does not work. |
To create objects for local variables, the program counter (PC) must be located within the function that contains the local variable of interest. Note also the static variables for which you are creating objects must be within the current scope as well.
To increase the accuracy of the information about global symbols in your project, use run, as shown here, to position the PC to the start of main in your application in CCS.
run(cc,'main')
Note that symbolname can be the name of a function in your target code. Thus, symbolname can refer to data or a function present on the target.
symbolname can be either a static variable or a global variable.
objname = createobj(cc,'symbolname','option') lets you declare more information about symbolname, such as whether it represents a static or global variable. Use one of the following strings to declare the type for symbolname in option:
static — declares that symbolname refers to a static variable in your code.
local — declares the symbol to be a local variable in your code.
global — declares that symbolname refers to a global variable in your code.
function — declares that symbolname refers to a function in your code. Refer to the next syntax for more information about this optional keyword.
objname = createobj(cc,'functionname','function','funcdecl',... 'function_declaration_string) creates a function object objname that accesses the function defined by function_declaration_string. Use the optional keywords function and funcdecl to specify that you are creating a function object, and the declaration string follows. This syntax is required to create function objects that access library functions, unless you use declare with an existing function object to provide the function declaration to MATLAB software.
Working with function objects is more complicated than working with the other object classes. A number of limitations and considerations apply when you create objects that access functions in your project.
createobj works without modification for the following kinds of functions:
Functions you write in C.
Functions you write in assembly but for which you provide C prototypes. One example of this kind is library functions that you call from your C programs in your project.
Using createobj to construct an object that accesses a function of the kind listed causes MATLAB software to search for the function declaration string in your project. When MATLAB software finds the prototype, it uses the declaration to create the information it needs to be able to run the function from MATLAB software, including
Objects that access the input parameters for the function
Objects that access the output parameter for the function
Storage locations and addresses for the function
If MATLAB software does not find the function, it creates the function object anyway, without the information it needs to run the function, and returns an error.
To respond to the error and provide MATLAB software the information it needs, use declare to provide the declaration string to MATLAB software.
You cannot create function objects for these kinds of functions:
Assembly functions that do not have C prototypes
Functions where the number of input arguments changes
Functions that include non-ANSI® C code
When you create a function object to access one of the above unsupported kinds, MATLAB software returns an error that it could not find the function declaration.
To allocate memory buffers for function objects that you create, use
objname = createobj(cc,functionname,'function','allocate',...
{'input',value1,'input2',value2,...});which lets you set aside memory for each function input, called input1, input2, and so on in the syntax. createobj assigns value1 and value2 to input1 and input2. allocate used here as a keyword specifies that this createobj syntax should perform memory allocation. So, to create memory buffers and assign values (12, 8, and 15) to three input variables for a function named filter, use the following syntax for createobj:
objname = createobj(cc,'filter','function','allocate',...
{'input1',12,'input2',8,'input3',15});Library functions present a special case of functions for Embedded IDE Link™ CC. createobj cannot find function declaration strings for library functions that you use in your project. While createobj does create the function object, it does not populate the function object with the information that enables MATLAB software to run the target function. For library functions you must use declare to define explicitly the function declaration for objects that access library functions. Or, when you create the function object, use the syntax
objname = createobj(cc,'functionname','function','funcdecl',... 'function_declaration_string');
that passes the declaration string to MATLAB software at creation time.
The following examples cover many situations you may encounter when you create function objects:
Run a C function.
Run a library function.
Run a function that includes a custom data type.
Run code generated by the Real-Time Workshop® software.
Run a function that uses input vectors.
Unless you have project code that supports the functions used here you cannot run these examples. They are for inspection only.
These examples refer to four functions — sin_taylor, dotprod, adotprod, and cdotprod. Here is the code for sin_taylor.
/*------------------------------------------------------------*
* Taylor Series expansion of sin function - Fixed Point
* Limitations: input range: -pi <x <pi;
*
* Input Datatype is:
* Q2.13 (or MATLAB sfix16_En13), scale factor = 2^13
* Output Datatype is:
* Q1.14 (or MATLAB sfix16_En14), scale factor = 2^14
*
* Taylor Expansion of sin function (first 4 terms)
* sin(x) =(approx) x[1 - (x^2/6)*[1 + (x^2/20)*[ 1 - (x^2/42)]]]
*-------------------------------------------------------------*/
#define SFIX32_EN26_VAL_1 67108864 // Integer equivalent of
1.0 in Q5.26
#define SFIX32_EN28_VAL_1 268435456 // Integer equivalent of
1.0 in Q3.28
#define SFIX32_EN30_VAL_1 1073741824 // Integer equivalent of
1.0 in Q1.30
short sin_taylor(short x)
{
// Define 16/32 bit local variables depending on processor
#if INT_MAX == 0x7FFFFFFF
int acc,a1,a2,a3,xpow;
#elif LONG_MAX == 0x7FFFFFFF
long acc,a1,a2,a3,xpow;
#endif
xpow = x*x; // x^2 sfix32_En26
a1 = xpow/42; // x^2/42 sfix32_En26
a2 = xpow/20; // x^2/20 sfix32_En26
a3 = xpow/6; // x^2/6 sfix32_En26
acc = SFIX32_EN26_VAL_1 - a1;
acc >>= 11;
acc *= (a2>>11);
acc = SFIX32_EN30_VAL_1 - acc;
acc >>= 14;
acc *= (a3>>14);
acc = SFIX32_EN28_VAL_1 - acc;
acc >>= 11;
acc *= x;
return (acc>>16);
}
In this example, we run function sin_taylor that computes the value for the sine of an input value. This function accepts one input, x (using data type short), and returns a short.
To get the correct values, the input data must be converted to Q16.13 format before passing to the function. After execution, the output value must be converted from Q16.14 to decimal representation.
Create a ticcs object that refers to the IDE:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding.
Run to start of main to ensure that your global variables are initialized:
run(cc,'main',1000);
Create a function object for sin_taylor:
ff = createobj(cc,'sin_taylor') inputdata = 0.5; % Input value to be used
Set value of input x:
x_obj = getinput(ff,'x'); write(x_obj,inputdata* 2^13);
Run the function:
outputdata = run(ff);
For a library function, you pass the declaration string explicitly through declare.
This example runs the function dotprod that computes the dot product of two arrays. This function requires three inputs:
x — a pointer to a vector of shorts
y — a pointer to a vector of shorts
n — the size of x and y vectors
We use the global variables a for input x, b for input y, and 4 for input nx (because a and b are four-element vectors). The function returns a short.
Create a ticcs object:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding
Run to start of main to ensure that you initialize the global variables:
run(cc,'main',1000); a_addr = address(cc,'a'); % Global buffer for 'x'. b_addr = address(cc,'b'); % Global buffer for 'y'.
Create the function object for the library function dotprod:
ff = createobj(cc,'dotprod')
The previous step yields an incomplete function object ff because library functions always require that you provide the function declaration explicitly, as follows:
declare(ff,'decl','int dotprod (short *x, short *y, int nx)')
Set the value for the input parameter x:
x_obj = getinput(ff,'x'); write(x_obj,a_addr(1)); xRef_obj = deref(x_obj); reshape(xRef_obj,4); x_inputval = read(xRef_obj) % Verify 'y' referent value.
Set the value for y, the second input parameter:
y_obj = getinput(ff,'y'); write(y_obj,b_addr(1)); yRef_obj = deref(y_obj); reshape(yRef_obj,4); y_inputval = read(yRef_obj) % Verify 'y' referent value.
Pass the value for nx to the function:
nx_obj = getinput(ff,'nx'); write(nx_obj,4); nx_inputval = read(nx_obj) % Verify 'nx' value.
Now run the function:
run(ff);
Having custom data types in your function declaration can cause problems when you run the functions from the ANSI C desktop.
This example runs the function cdotprod that computes the dot product of two matrices. This function requires three inputs:
x — a pointer to a vector of shorts
y — a pointer to a vector of shorts
n — the size of x and y vectors
Both n and the return argument are defined as data type INT, a custom data type defined in the source code.
We use the global variables a for input x, b for input y, and 4 for input n (because a and b are four-element vectors). The function returns a short.
Create a ticcs object:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding
Run to start of main to ensure that CCS initializes all of the global variables:
run(cc,'main',1000); a_addr = address(cc,'a'); % Global buffer for x. b_addr = address(cc,'b'); % Global buffer for y.
Create a function object for the library function cdotprod:
ff = createobj(cc,'cdotprod')
The previous call to createobj yields an incomplete function object because the function declaration includes an unresolved typedef — the type INT. To resolve this error, add the custom data type INT to the type object and use declare to pass the function declaration to ANSI C software:
add(cc.type,'INT','int'); % A warning mentions that data type
% INT cannot be resolved.
declare(ff,'decl','INT cdotprod (short x[], short y[], INT n)')
Set values for the inputs x, y, and n, and run the function, passing the input values in the run syntax. Input x is a pointer so pass an address. Input y is a pointer as well, so pass another address. Input n is an integer that specifies the size of x and y:
run(ff,'x',a_addr(1),'y',b_addr(1),'n',4);
We are going to run the function cdotprod, which computes the dot product of two matrices. This function accepts three inputs:
x — a pointer to a vector of shorts
y — a pointer to a vector of shorts
n — the size of x and y vectors
We use the global variable a for input x, b for input y, and 4 for input n (because a and b are four-element vectors). The function returns a short.
Create ticcs object:
cc = ticcs; reset(cc); Pause(1); % Wait for hardware reset to complete before proceeding.
Run to start of main to ensure that CCS initializes all of the global variables:
run(cc,'main',1000); a_addr = address(cc,'a'); % Global buffer for 'x'. b_addr = address(cc,'b'); % Global buffer for 'y'.
Create function object for library function cdotprod:
ff = createobj(cc,'cdotprod')
Again createobj generates an incomplete function object because of the unresolved data type INT in the function declaration. In this case, fix the problem by adding the custom data type INT to the type object and create the object ff again, instead of using declare to pass the function declaration to ANSI C software:
add(cc.type,'INT','int'); % Warning mentioned that data type
% INT cannot be resolved.
ff = createobj(cc,'cdotprod')
Set values for the inputs x, y, and n, and run the function, passing the input values in the run syntax. Input x is a pointer so pass an address. Input y is a pointer as well, so pass another address. Input n is an integer that specifies the size of x and y:
run(ff,'x',a_addr(1),'y',b_addr(1),'n',4);
Once more we are going to run the function cdotprod, which computes the dot product of two matrices. This function accepts three inputs:
x — a pointer to a vector of shorts
y — a pointer to a vector of shorts
n — the size of x and y vectors
We use the global variable a for input x, b for input y, and 4 for input n (because a and b are four-element vectors). cdotprod returns a short.
Create ticcs object:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding.
Run to start of main to ensure that CCS initializes all of the global variables:
run(cc,'main',1000); a_addr = address(cc,'a'); % Global buffer for x. b_addr = address(cc,'b'); % Global buffer for y.
Create a function object for the library function cdotprod:
ff = createobj(cc,'cdotprod')
This attempt to create a new function object ff results in an incomplete function object because ANSI C software could not resolve the data type INT in the function declaration. In this approach to overcoming the unresolved type error, use declare to pass to ANSI C software a version of the cdotprod function declaration that does not include the offending type INT — you do not need to add the typedef to the type object:
declare(ff,'decl','int cdotprod (short x[], short y[], short n)')
Notice that the data types for the return argument and for n now specify int, Set values for the inputs x, y, and n, and run the function, passing the input values in the run syntax. Input x is a pointer so pass an address. Input y is a pointer as well, so pass another address. Input n is an integer that specifies the size of x and y:
run(ff,'x',a_addr(1),'y',b_addr(1),'n',4);
We are going to run the function 'mwdsp_fir_df_dd' which applies a filter to a noisy input signal. This function accepts nine input parameters and returns the filtered signal in the input argument y.
Create a ticcs object:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding.
Now run the generated code from the beginning to MdlOutputs. You run from program start until MdlOutputs to ensure that all of the code configuration processes get done:
run(cc,'runtofunc',MdlOutputs);
After running to MdlOutputs, you create the function object — pass the function declaration to avoid MATLAB software returning an error when you create the function object. Due to the complexity of this function declaration, we have assigned the string to a variable decl. We use the variable in the createobj syntax.
decl = ['MWDSP_IDECL void MWDSP_FIR_DF_DD(const real_T *u,... real_T *y, real_T * const mem_base,int_T *mem_offset,... const int_T numDelays, const int_T sampsPerChan,... const int_T numChans, const real_T * const b,... const boolean_T one_fpf)']; ff = createobj(cc,'MWDSP_FIR_DF_DD','function','funcdecl',decl);
Examine the function declaration above. This declaration causes MATLAB software to fail to create the fully populated function object ff because of the MWDSP_IDECL macro at the beginning of the string. MATLAB software cannot recognize this string. Because the information in MWDSP_IDECL is not relevant to creating the function object, you can remove this from the declaration string:
decl = ['void MWDSP_FIR_DF_DD(const real_T *u,... real_T *y, real_T * const mem_base,int_T *mem_offset,... const int_T numDelays, const int_T sampsPerChan,... const int_T numChans, const real_T * const b,... const boolean_T one_fpf)']; ff = createobj(cc,'MWDSP_FIR_DF_DD','function','funcdecl',decl);
Now function object ff has all the information MATLAB software needs.
Note You may not always be able to remove offending entries in a declaration string, as we did with the macro MWDSP_IDECL. Often you can try your declaration and see if it works. If not, use add to include typedefs in the type object when MATLAB software complains about a data type, or try removing the problem portion of the declaration string if the function does not require the troublesome text. |
With the function object in your MATLAB workspace, create objects for the inputs to MWDSP_FIR_DF_DD:
Create an object for rtB:
rtBobj = createobj(cc,'rtB');
Get the relevant rtB member objects:
SumObj = getmember(rtBobj,'Sum'); % Store Output of MWDSP_FIR_DF_DD in FilObj FilObj = getmember(rtBobj,'Digital_Lowpass_Fil');
Next, create an object for rtDWork:
rtDWorkObj = createobj(cc,'rtDWork');
and get the relevant member objects:
Fil_FILT_STATES = getmember(rtDWorkObj,... 'Digital_Lowpass_Fil_FILT_STATES'); DF_INDX = getmember(rtDWorkObj,... 'Digital_Lowpass_Fil_FILT_STATES');
Create one last object for filterCoeffs:
filterCoeffsObj = createobj(cc,'filterCoeffs');
To run the function, you need to provide the input values:
u = SumObj.address(1); % Input 1. y = FilObj.address(1); % Input 2. mem_base = Fil_FILT_STATES.address(1); % Input 3. mem_offset = DF_INDX.address(1); % Input 4. numDelays = 65; % Input 5. sampsPerChan = 256; % Input 6. numChans = 1; % Input 7. b = filterCoeffsObj.address(1); % Input 8. one_fpf = 1; % Input 9.
Run the function, providing the input argument values in input value/input name pairs, such as 3,membase and 6,sampPerChan:
run(ff,1,u,2,y,3,mem_base,4,mem_offset,5,numDelays,6,... sampsPerChan,7,numChans,8,b,9,one_fpf)
This example shows how to run a function that accepts vector inputs.
We are going to run the function adotprod that computes the dot product of two matrices. adotprod accepts two inputs,
x — a four-element vector of shorts
y — a four-element vector of shorts
The compiler converts the vector inputs into pointers to the vectors. We use the global variable a for input x and b for input y. The function returns a short.
Create a ticcs object:
cc = ticcs; reset(cc); pause(1); % Wait for hardware reset to complete before proceeding.
Run to start of main to ensure that CCS initializes all of the global variables:
run(cc,'main',1000); a_addr = address(cc,'a'); % Global buffer for 'x'. b_addr = address(cc,'b'); % Global buffer for 'y'.
Create a function object ff to access adotprod:
ff = createobj(cc,'adotprod')
The function prototype for adotprod is
int adotprod(short x[4], short y[4])
adotprod requires as input two vector arrays x and y. The compiler requires that you pass the addresses of x[4] and y[4], not the actual vectors x and y. So instead of writing a data vector to input object x_obj and y_obj, you provide the addresses of existing four-element vectors:
display('INPUT VALUE ''x'':')
x_obj = getinput(ff,'x') % Note that this is a pointer to a vector
% of shorts
display('INPUT VALUE ''y'':')
y_obj = getinput(ff,'y') % Note that this is a pointer to a vector
% of shorts
Set value of inputs x and y and run the function. Pass addresses to x and y because both are pointers to other data:
write(x_obj,a_addr(1)) write(y_obj,b_addr(1)) x_inputval = read(reshape(deref(x_obj),4)); y_inputval = read(reshape(deref(y_obj),4));
Using the following commands to write data to x and y does not give you the expected result — the compiler cannot determine where to put array [1:4]:
write(x_obj,[1:4]); write(y_obj,[1:4]);
Now run your function:
run(ff);
The preceding examples present a few of the wide variety of functions and conditions you may encounter when you construct function objects.
![]() | copy | datatypemanager | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |