If your generated code must meet a specific coding pattern or you want more flexibility, for example, to further improve performance, you can remap operator outputs to input positions in an implementation function argument list.
Note
Remapping outputs to implementation function inputs is supported only for operator replacement.
For example, for a sum operation, the code generator produces code similar to:
add8_Y.Out1 = u8_add_u8_u8(add8_U.In1, add8_U.In2);
If you remap the output to the first input, the code generator produces code similar to:
u8_add_u8_u8(&add8_Y.Out1;, add8_U.In1, add8_U.In2);
The following table definition file for a sum operation remaps
operator output y1
as the first function input
argument.
Create a table definition file that contains a function definition. For example:
function hTable = crl_table_add_uint8
Within the function body, create the table by calling
the function RTW.TflTable
.
hTable = RTW.TflTable;
Create an entry for the operator mapping with a call
to the RTW.TflCOperationEntry
function.
% Create operation entry
op_entry = RTW.TflCOperationEntry;
Set operator entry parameters with a call to the setTflCOperationEntryParameters
function.
In the function call, set the property SideEffects
to true
.
setTflCOperationEntryParameters(op_entry, ... 'Key', 'RTW_OP_ADD', ... 'Priority', 90, ... 'ImplementationName', 'u8_add_u8_u8', ... 'ImplementationHeaderFile', 'u8_add_u8_u8.h', ... 'ImplementationSourceFile', 'u8_add_u8_u8.c', ... 'SideEffects', true );
Create conceptual arguments y1
, u1
,
and u2
. There are multiple ways to set up the conceptual
arguments. This example uses calls to the getTflArgFromString
and addConceptualArg
functions to create
and add the arguments.
arg = getTflArgFromString(hTable, 'y1', 'uint8'); arg.IOType = 'RTW_IO_OUTPUT'; addConceptualArg(op_entry, arg); arg = getTflArgFromString(hTable, 'u1', 'uint8'); addConceptualArg(op_entry, arg ); arg = getTflArgFromString(hTable, 'u2', 'uint8'); addConceptualArg(op_entry, arg );
Create the implementation arguments. There are multiple
ways to set up the implementation arguments. This example uses calls
to the getTflArgFromString
function
to create the arguments. When defining the implementation function
return argument, create a new void
output argument,
for example, y2
. When defining the implementation
function argument for the conceptual output argument (y1
),
set the operator output argument as an additional input argument.
Mark its IOType
as output. Make its type a pointer
type. The convenience methods setReturn
and addArgument
specify
whether an argument is a return value or argument and adds the argument
to the entry’s array of implementation arguments.
% Create new void output y2 arg = getTflArgFromString(hTable, 'y2', 'void'); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.setReturn(arg); % Set y1 as first input arg, mark IOType as output, and use pointer type arg=getTflArgFromString(hTable, 'y1', 'uint8*'); arg.IOType = 'RTW_IO_OUTPUT'; op_entry.Implementation.addArgument(arg); arg=getTflArgFromString(hTable, 'u1', 'uint8'); op_entry.Implementation.addArgument(arg); arg=getTflArgFromString(hTable, 'u2', 'uint8'); op_entry.Implementation.addArgument(arg);
Add the entry to a code replacement table with a call
to the addEntry
function.
addEntry(hTable, op_entry);
Save the table definition file. Use the name of the table definition function to name the file.
To test this example:
Register the code replacement mapping.
Create a model that includes an Add block.
Configure the model with the following settings:
On the Solver pane, select a fixed-step solver.
On the Code Generation pane, select an ERT-based system target file.
On the Code Generation > Interface pane, select the code replacement library that contains your addition operation entry.
Set the Optimize global data access parameter to
Use global to hold temporary results
to reduce data
copies in the generated code.
Generate code and a code generation report.
Review the code replacements.