You can integrate new or existing C code into Simulink® using the C Caller block. To create custom blocks in your Simulink models, the C Caller block allows you to call external C functions specified in external source code and libraries. The advantages of the C Caller block are:
Automated integration of simple C functions
Integration with Simulink Coverage™, Simulink Test™, and Simulink Design Verifier™
Integration with Simulink Coder™
The C Caller block allows you to bring C algorithms into Simulink. To model dynamic systems, use the S-Function Builder instead. Next steps describe the workflow to integrate C code into Simulink using the C Caller block.
Specify your external source code file that contains your C functions.
From Simulink toolstrip, open the Configuration Parameters.
In the left pane, select Simulation Target.
To enable code parsing by the C Caller block, ensure that the Import custom code box is selected.
The directories and file paths can be absolute and relative file paths to model directories or to the current working directory. See Specify Relative Paths for Custom Code (Stateflow).
Select Header file and enter the name of your header file
with the #include
tag.
Under Additional build information, select Include directories, and enter the folders where additional build information, such as header files, are stored.
Select Source files and enter the path and the name of the source file. If the model and the source files are in different directories, enter the directory that contains the source file before the file name.
If a function is declared in the header file, but not implemented in the source code, an empty stub function is automatically generated to simulate and compile the model.
You can specify the order of how your matrix data is stored in Simulink. Matrix data passed to and from your C functions is converted to the default function array layout you specified. If the function array layout is not specified, the matrix data is passed through the C Caller in the same order of your Simulink data, and computational errors may occur due to row-column major disarrangement. Ensure that you follow the same default function array layout for all Simulink data.
Column-Major — The C Caller block handles Simulink data in column-major order. Suppose that you have a 3-by-3 matrix. In the C Caller block, this matrix is stored in the sequence: first column, second column, and third column.
Row-Major — The C Caller block handles Simulink data in row-major order. Suppose that you have a 3-by-3 matrix. In C Caller block, this is stored in the sequence: first row, second row, and third row.
Any — Array data can be stored both in column-major and row-major in the C Caller block. You can generate code both in column and row-major settings.
Not specified — Array data can be stored in both column-major and row-major order. Compared to Any setting, you can only generate code in column-major setting.
To learn more about the row and column major array layouts in Simulink, see Default function array layout.
Select an array layout option under Default Array Function Layout.
If you need to apply a specific array layout to some of the functions in your code, click on Specify by Function to choose these functions.
Click Apply to accept your changes.
Click OK to close the Configuration Parameters.
You can start your custom C code integration into Simulink simply by typing C Caller into Simulink canvas. Alternatively, drag a C Caller block from the Library Browser > User-Defined Functions. Double-click the block to open Block Parameter dialog box to see the names of your functions and port specifications.
Click on the on the Refresh custom code to import your source code and its
dependencies.
Your C functions are displayed under Function Name. If you
can't see your full list of functions, click on the to reimport your source code.
To view function declarations, or input/output variables to your functions in the
header file, click on the Go to function declaration
to navigate the source files.
To change source files and their dependencies, or to define and select function
array layouts, click the Custom code settings
to open the Simulation
Target tab in Configuration Parameters.
You can map your C function arguments from your source code to Simulink ports using the Port specification in the C Caller block. In your source code, the header file includes the C function arguments to be connected to Simulink ports.
extern void mean_filter(const unsigned char* src, unsigned char* dst, unsigned int width, unsigned int height, unsigned int filterSize);
Port specification shows the details of your arguments and how they connect to your C Caller block in Simulink.
Arg name — Specifies the name of input and output arguments. Arg name is the function argument or parameter name as defined in your C functions from your source code. This column is only for reference purposes.
Scope — Specifies how C function arguments map to the Simulink scope. Your arguments have default scopes depending on the function definition and you can change the scopes depending your function definition in the source code.
Simulink scope | C Argument |
---|---|
input | block input port |
output | block output port |
parameter | block tunable parameter |
constant | a constant value |
When you have a constant qualifier definition such as const double
*u
, the argument can only be an input or a parameter. When there is no constant
qualifier, the argument is an output by default, and you can change it to an input or
parameter. In this case, ensure that the C function does not modify the memory pointed by
the pointer. If the argument is of an output type, every element pointed by this pointer
should be reassigned in every call for this function.
C argument | Simulink scope |
---|---|
function return | output |
| output (default), input, parameter |
| input (default), parameter |
Label — Indicates the label for the corresponding argument in a Simulink block. By default, your argument label is same with the argument name unless you change it.
Simulink scope | Label |
---|---|
input, output | port name |
parameter | parameter name |
constant | expression for the constant value. size expressions using
input argument names, for example |
Type — Demonstrates the matching Simulink data type to the C function argument data type.
C argument data type | Simulink data type |
---|---|
signed char | int8 |
unsigned char | uint8 |
char | int8 or uint8, depending on the compiler |
int* | int32 |
unsigned int* | uint32 |
short * | int16 |
long * | int32 or fixdt(1,64,0), depending on the operating system |
float | single |
double | double |
int8_t* | int8 |
uint8_t* | int8 |
int16_t* | int16 |
uint16_t* | uint16 |
int32_t* | int32 |
uint32_t* | uint32 |
typedef struct {…} AStruct** | Bus: AStruct |
typedef enum {..} AnEnum** | Enum: AnEnum |
* If C Caller takes an integer type, for example, int16_t, you can modify it to a fixed point type with matching base type, for example to fixdt(1, 16, 3). ** The C Caller sync button prompts you to import struct or enum types used by a C function as Simulink bus and enumeration types. |
Size — Specifies the data dimensions in the argument.
C argument dimensions | Simulink port dimensions |
---|---|
| scalar (1) |
| inherited (-1) (default) If the argument is for an output port, size should be specified. Size of an output port cannot be inherited. |
| size is [2, 3] |
You can create a library model to group your C Caller blocks and keep your models organized.
Open a new library model from File > New > Library and click Blank Library.
Open Simulation Target from View > Library Custom Code Settings > Simulation Target
Select C
or C++
in the
Language option, depending on your code, and ensure the
Import custom code box is checked.
Follow the instructions in Specify Source Code and Dependencies to add your source files and their dependencies.
Create C Caller blocks to call C functions.
To insert a block from your library model to the Simulink models, simply drag the block into your model.
Global Initialization of C States — If your C functions read or write global or static variables, beware on the use. For example, if multiple C functions are accessing the same set of global variables, the execution order of the blocks may lead to unexpected results.
Initialization/Termination of Custom Code Settings — If you need to allocate and deallocate memory for your custom code, insert allocate and deallocate in the Initialize function and Terminate function fields of custom code settings.
Complex Data Support — The C Caller block doesn't support complex data type in Simulink.
Continuous Sample Time — The C Caller block doesn't support continuous sample time.
Variable Arguments — Variable arguments in C are
not supported. For example, int sprintf(char *str, const char *format,
...)
C++ Syntax — The C Caller block does not support native C++ syntax directly. You need to write a C function wrapper to interface with C++ code.
To test your models that includes C Caller blocks, see Test Integrated C Code (Simulink Test)
MATLAB Function | MATLAB System | S-Function | S-Function Builder | legacy_code