Call and Integrate External C Algorithms into Simulink

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 and Terminate Code panes in the block parameters dialog. Use C Function block to:

  • Call functions from external C code, 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.

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 */
        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. In a new, blank model, 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 Configuration Parameters dialog. In the Simulation Target pane, define your header file under Insert custom C code in generated: > Header file.

  3. Define the source file under Additional build information > Source files.

    Click OK to close the Configuration Parameters.

  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;
    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 external C code. Add or delete a symbol using the Add and Delete buttons. Define all symbols used in the Output Code, Start Code, and Terminate Code panes to ensure that ports display correctly.

    In the Symbols table, define the following.

    • Name — Symbol name in the source code.

    • Scope — Scope of the symbols and the order in which they appear. You can change the scope of a symbol at any time.

      • Input — Input symbol to the C Function block.

      • Output — Output symbol to the C Function block.

      • Persistent — Define a symbol as persistent data.

        You can define a void pointer using the Persistent scope in the C Function block. A void pointer is a pointer that can store any type of data that you created or allocated.

      • Constant — Define a symbol as constant using value-size or numeric expressions.

      • Parameter — Define a symbol as parameter. The parameter name is defined by the Label of the symbol.

    • Label — Label of the symbol. For symbols with their scope set to Input or Output, this label appears as the port name on the block. For symbols with their scope set to Parameter, this label is the label that appears on the block parameter mask. You cannot define a label for Persistent symbols. If the scope is Constant, the label is the constant expression.

    • Type — Data type of the symbol. Select a data type from the drop-down list or specify a Simulink.AliasType object.

    • Size — Size of the symbol data. The C Function block supports only scalars and vectors are supported. Matrices and higher-dimension arrays are not supported. You can use a size expression to define the size of an output. Use -1 to inherit size.

    • Port — For input and output symbols, Port indicates the port index on the block of the symbol data. For parameter symbols, Port indicates the order that the symbol appears in the block parameter mask.

    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.

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, you use the following.

#ifdef MATLAB_MEX_FILE
/* Enter Sim Code */
#else 
/* Enter code generation code */
#endif

See Also

Functions

Objects

Blocks