Main Content

Call External C Functions

About This Example

Learning Objectives

  • Evaluate a C function as part of a model simulation.

  • Call an external C function from generated code.

Prerequisites

  • Ability to open and modify Simulink® models and subsystems.

  • Ability to set model configuration parameters.

  • Ability to read C code.

  • An installed, supported C compiler.

Required Files

  • Model files ThrottleControlExtFuncCall and ThrottleControlTestHarness

  • SimpleTable.c

  • SimpleTable.h

Include External C Functions in a Model

Simulink models are one part of Model-Based Design. For many applications, a design also includes a set of pre-existing C functions created, tested (verified), and validated outside of a MATLAB® and Simulink environment. You can integrate these functions easily into a model and the generated code. You can use external C code in the generated code to access hardware devices and external data files during rapid simulation runs.

Open Example Model

This example shows you how to create a custom block that calls an external C function. When the block is part of the model, you can take advantage of the simulation environment to test the system further.

Open the model ThrottleControlExtFuncCall and the test harness model ThrottleControlTestHarness. You can use these models to validate your external C code.

Model ThrottleControlExtFuncCall.

open_system('ThrottleControlExtFuncCall')

Test harness ThrottleControlTestHarness.

open_system('ThrottleControlTestHarness')

Create a Block That Calls a C Function

To specify a call to an external C function, use an S-Function block. You can automate the process of creating the S-Function block by using the Simulink Legacy Code Tool. Using this tool, specify an interface for your external C function. The tool then uses that interface to automate creation of an S-Function block.

  1. Create an S-Function block that calls the specified function at each time step during simulation:

    1. In the MATLAB Command Window, create a function interface definition structure:

      def=legacy_code('initialize')

      The data structure def defines the function interface to the external C code.

      def = 
      
                        SFunctionName: ''
          InitializeConditionsFcnSpec: ''
                        OutputFcnSpec: ''
                         StartFcnSpec: ''
                     TerminateFcnSpec: ''
                          HeaderFiles: {}
                          SourceFiles: {}
                         HostLibFiles: {}
                       TargetLibFiles: {}
                             IncPaths: {}
                             SrcPaths: {}
                             LibPaths: {}
                           SampleTime: 'inherited'
                              Options: [1x1 struct]
    2. Populate the function interface definition structure by entering these commands. When you opened the model ThrottleControlExtFuncCall, the files SimpleTable.c and SimpleTable.h were copied to your working folder.

      def.OutputFcnSpec=['double y1 = SimpleTable(double u1,',...
         'double p1[], double p2[], int16 p3)'];
      def.HeaderFiles = {'SimpleTable.h'};
      def.SourceFiles = {'SimpleTable.c'};
      def.SFunctionName = 'SimpTableWrap';
    3. Create the S-function:

      legacy_code('sfcn_cmex_generate', def)
    4. Compile the S-function:

      legacy_code('compile', def)
    5. Create the S-Function block:

      legacy_code('slblock_generate', def)

      A new model window opens that contains the SimpTableWrap block.

      Tip

      Creating the S-Function block is a one-time task. Once the block exists, you can reuse it in multiple models.

  2. Save the model to your working folder as: s_func_simptablewrap.

  3. Create a Target Language Compiler (TLC) file for the S-Function block:

    legacy_code('sfcn_tlc_generate', def)

    The TLC file is the component of an S-function that specifies how the code generator produces the code for a block.

For more information on using the Legacy Code Tool, see:

Validate C Code as Part of a Model

Validate the S-function in the model. Use the model ThrottleControlExtFuncCall and test harness ThrottleControlTestHarness that you opened earlier to complete the validation.

Note

The following procedure requires a Stateflow® license.

  1. In ThrottleControlExtFuncCall, examine the PI_ctrl_1 and PI_ctrl_2 subsystems.

    1. Lookup blocks have been replaced with the block you created using the Legacy Code Tool.

    2. Examine the block parameter settings for SimpTableWrap and SimpTableWrap1.

    3. Close the Block Parameter dialog boxes and the PI subsystem windows.

  2. In the test harness model ThrottleControlTestHarness, right-click the Unit_Under_Test Model block, and select Block Parameters (ModelReference).

  3. Set Model name to ThrottlecontrolExtFuncCall. Click OK.

  4. Update the test harness model diagram.

  5. Simulate the test harness.

    The simulation results match the expected golden values.

Call a C Function from Generated Code

The code generator uses a TLC file to process the S-Function block. Calls to C code embedded in an S-Function block:

  • Can use data objects.

  • Are subject to expression folding, an operation that combines multiple computations into a single output calculation.

  1. Generate code for the model ThrottleControlExtFuncCall.

  2. Examine the generated code in the fileThrottleControlExtFuncCall.c.

Key Points

  • You can easily integrate external functions into a model and generated code by using the Legacy Code Tool.

  • Validate the functionality of external C function code which you integrate into a model as a standalone component.

  • After you validate the functionality of external C function code as a standalone component, validate the S-function in the model.

Related Topics