Main Content

Integrate External C/C++ Code into Simulink Using C Function Blocks

You can call and integrate your external C code into Simulink® models using C Function blocks. C Function blocks allow you to call external C code and customize the integration of your code using the Output Code, Start Code, Initialize Conditions Code, and Terminate Code panes in the block parameters dialog. Use the C Function block to:

  • Call functions from external C code including functions defined under namespace, and customize the code for your Simulink models.

  • Preprocess data to call a C function and postprocess data after calling the function.

  • Specify different code for simulation and code generation.

  • Call multiple functions.

  • Initialize and work with persistent data cached in the block.

  • Allocate and deallocate memory.

Use the C Function block to call external C algorithms into Simulink that you want to modify. To call a single C function from a Simulink model, use the C Caller block. To integrate dynamic systems that have continuous states or state changes, use the S-Function block.

Note

C99 is the standard version of C language supported for custom C code integration into Simulink.

The following examples use C Function blocks to calculate the sum and mean of inputs.

Write External Source Files

Begin by creating the external source files.

  1. Create a header file named data_array.h.

    /* Define a struct called DataArray */
    typedef struct DataArray_tag {
        /* Define a pointer called pData */
        const double* pData;
        /* Define the variable length */
        int length;
    } DataArray;
    
    /* Function declaration */
    double data_sum(DataArray data);

  2. In the same folder, create a new file, data_array.c. In this file, write a C function that calculates the sum of input numbers.

    #include "data_array.h"
    
    /* Define a function that takes in a struct */
    double data_sum(DataArray data)
    {
        /* Define 2 local variables to use in the function */
        double sum = 0.0;
        int i;
        /* Calculate the sum of values */
        for (i = 0; i < data.length; i++) {
            sum = sum + data.pData[i];
        }
        /* Return the result to the block */
        return sum;
    }

Enter the External Code Into Simulink

  1. Create a new, blank model and add a C Function block. The C Function block is in the User-Defined Functions library of the Library Browser.

  2. Double-click the C Function block to open the block dialog. Click to open the Model Configuration Parameters dialog. In the Simulation Target pane, define your header file under Include headers on the Code information tab.

    Custom Code section of Simulation Target pane of Model Configuration Parameters dialog. Code information tab and Include headers field are highlighted. The following text is entered in the field: #include "data_array.h"

    Tip

    After you have entered information for Source file in the next step, you can click Auto-fill from Source files to have the header file name filled in automatically, using information contained in your source files.

  3. Define the source file under Source files on the Code Information tab. To verify that your custom code can be parsed and built successfully, click Validate custom code.

    Custom Code section of Simulation Target pane of Model Configuration Parameters dialog. Code information tab and Source files field are highlighted. The following text is entered in the field: data_array.c

    Note

    To use a C Function block in a For Each subsystem or with continuous sample time, or to optimize the use of the block in conditional input branch execution, all custom code functions called by the block must be deterministic, that is, always producing the same outputs for the same inputs. Identify which custom code functions are deterministic by using the Deterministic functions and Specify by function parameters in the Simulation target pane. If the block references any custom code global variables, then Deterministic functions must set to All in order for the block to be used in a For Each subsystem, in conditional input branch execution, or with continuous sample time.

    For an example showing a C Function block in a For Each subsystem, see Use C Function Block Within For Each Subsystem.

  4. In the Output Code pane of the C Function block parameters dialog, write the code that the block executes during simulation. In this example, the external C function computes a sum. In the Output Code pane, write code that calls the data_array.c function to compute the sum, then computes the mean.

    /* declare the struct dataArr */
    DataArray dataArr;
    /* store the length and data coming in from the input port */
    dataArr.pData = &data[0];
    dataArr.length = length;
    
    /* call the function from the external code to calculate sum */
    sum = data_sum(dataArr);
    
    /* calculate the mean */
    mean = sum / length;

    You can specify code that runs at the start of a simulation and at the end of a simulation in the Start Code and Terminate Code panes.

  5. Use the Symbols table to define the symbols used in the code in the block. Add or delete a symbol using the Add and Delete buttons. Define all symbols used in the Output Code, Start Code, Initialize Conditions Code, and Terminate Code panes to ensure that ports display correctly.

    In the Symbols table, for each symbol used in the code in the block, define the Name, Scope, Label, Type, Size, and Port, as appropriate.

    Close the block parameters dialog. After filling in the data in the table, the C Function block now has one input port and two output ports with the labels specified in the table.

  6. Add a Constant block to the Simulink canvas that will be the input to the C Function block. In the Constant block, create a random row array with 100 elements. To display the results, attach display blocks to the outputs of the C Function block.

Note

If a model has custom code, after the model is updated or run, the slprj folder may be locked due to the loaded custom code simulation executable file. You cannot delete the folder when it is locked. To unload the executable file and unlock the slprj folder, use the clear mex command. See clear.

Specify Simulation or Code Generation Code

You can specify different Output Code for simulation and code generation for the C Function block by defining MATLAB_MEX_FILE. For example, to specify code that only runs during the model simulation, use the following.

#ifdef MATLAB_MEX_FILE
/* Enter simulation code */
#else 
/* Enter code generation code */
#endif

Specify Declaration for Target-Specific Function for Code Generation

For code generation purposes, if you do not have the external header file with the declaration of a function (such as a target-specific device driver) that you want to call from the C Function block, you can include a declaration with the correct signature in the Output Code pane of the block. This action creates a function call to the expected function when code is generated, as in the following example:

#ifndef MATLAB_MEX_FILE
extern void driverFcnCall(int16_T in, int16_T * out);
driverFcnCall(blockIn, &blockOut);
#endif

See Also

Functions

Objects

Blocks

Related Topics