3.2.2. Procedure

To create a S-function, begin by copying the files listed below from the directory:

[OpenECU install directory]\examples\simulink\two_pot_demo_w_sfunction\tpd\

to a data dictionary directory of your model directory:

[your model directory]\[data dictionary directory]

xx_code.h

This file defines the interface to the C source code.

xx_code_wrapper.c

This file tells MATLAB how to simulate the S-function block.

xx_code_wrapper.tlc

This file tells MATLAB how to generate code for the S-function block.

xx_code.c

This file implement's the user's algorithms as C source code.

rtwmakecfg.m

This file tells MATLAB where the C source code is located.

The xx part of the file name represents the core function of the S-function and it's up to the user to choose an appropriate name. If multiple S-functions are created then each function should have a unique set of files.

As the OpenECU model load scripts add each of the data dictionary directories to MATLAB's path, then by placing the files in a data dictionary directory MATLAB will be able to find the S-function and the hand-written C code is located.

Note

Some versions of MATLAB and OpenECU cannot correctly deal with paths that include spaces. Make sure the path of the model directory doesn’t have any spaces (e.g. a good example is C:\TestModel\drc\; a bad example is C:\Documents and Settings\Test Model\drc\).

The xx_code.h, xx_code_wrapper.c, xx_code_wrapper.tlc and xx_code.c files have step by step instructions embedded within the code. Changes will be required to parts of the code following comments which look like:

/*
 *****************************************************************************
 * Step n:
 * ...
 ******************************************************************************
 */

The number n is the step number and each step is explained below. Other sections of the code are generic and do not need to be altered. Follow the steps below in sequence to create a S-function which implements custom C code.

Begin by editing the xx_code.h file:

  1. Replace the literal TPD_CODE_H with a name unique across all source files, to protect against double inclusion.

  2. Define the data types and assign names for the inports and outports of the S-function.

    Note

    These are the name that will be used to pass data from Simulink into the C code and from C code to Simulink via the inports and outports.

Edit the xx_code_wrapper.c file:

  1. Define S_FUNCTION_NAME as the S-function wrapper name.

  2. Include the S-function C code file (i.e xx_code.c).

  3. Define the number of arguments, inports and outports used in the S-function.

    Note

    In this example, the S-function does not use any input arguments, so the number of arguments is set to 0. For more information on how to use input arguments, please refer to the S-function block’s help section.

  4. Define the properties of each inport used in the S-function.

  5. Define the properties of each outport used in the S-function.

  6. Get hold of storage locations of the data being sent from Simulink to the S-function via the inports.

  7. Get hold of storage locations of the data that is going to be sent to Simulink from the S-function via the outports.

    Note

    The port numbers start from 0 and not 1. For more information on the property functions, search for the section named “Writing S-functions” or search using the property function name under MATLAB's help.

  8. Pass the data received from Simulink via the inports to the C code.

  9. Pass the data received from the C code to Simulink via the outports.

Edit the xx_code.c file.

  1. Include the header file for the S-function.

  2. Add the variables used in the S-function that need to be calibratable.

    Note

    The variable should have a four letter prefix with the fourth letter set to c (e.g. mbec_maximum_engine_speed). See the variable naming requirements in section Section 8.2.5, “Naming rules”.

  3. This is where the main algorithm is going to be located.

Edit the xx_code_wrapper.tlc file:

  1. Update %implements directive with the S-function wrapper name.

  2. Include the S-function C code header file (i.e xx_code.h).

  3. Include the S-function C code file (i.e xx_code.c).

  4. Pass the data received from Simulink via the inports to the C code.

  5. Execute the C-code function.

  6. Pass the data received from the C code to Simulink via the outports.

After making changes to the source code, do the following:

  1. MEX Setup

    • Change MATLAB path to the data dictionary directory where the C files are.

    • Issue the command

      mex –setup

      at MATLAB's command prompt and when prompted with the question: “Would you like mex to locate installed compilers [y]/n?”, enter Y.

    • Then choose the number associated with the desired compiler and when prompted with the question: “Are these correct?”, enter Y.

    Note

    This step need to be done once and MATLAB will remember these settings each time it is opened.

  2. Compile and Link Source Files

    • Change MATLAB path to the data dictionary directory where the C files are.

    • Issue the command

      mex xx_code_wrapper.c

      at MATLAB's command prompt.

    • If there are no errors, MATLAB will compile and link the source files into a DLL file but won’t give any confirmation that the compilation was successful. The DLL file is used by Simulink to create the S-function block with an appropriate number of inports and outports, and to perform the C source code algorithms when simulating the model.

    • If there are errors, MATLAB will display and errors in the command window. Fix the errors and re-issue the previous command.

    Note

    These steps need to be done each time the S-function or algorithm C code is altered for the new changes to take effect.

  3. Run the Model

    • Change MATLAB path to the model directory and open the model.

    • Insert an S-function block from the User-Defined Function.

    • Double-click on the block to open it. In the S-function Name field insert the name of the wrapper i.e xx_code_wrapper.

    • Click OK and then click update.

    • If there has been no problem with the previous steps, the inports and outports on the S-function block will appear. The block is now ready to be used when simulating or building the model.

    • If the source files were not compiled and linked into a DLL, the following error will be displayed “Error in S-function 'model directory/model name/S-function name': S-function 'xx_code_wrapper' does not exist”.

The S-function is now ready to be used when simulating or building the model. Each time the C sources are modified, the S-function must be built manually by issing the mex command. However, it is possible to build the S-function automatically by adding a callback function to the S-function block. The advantage is that Simulink invokes the callback before the model is simulated, updated or built, ensuring the S-function is up to date regardless of whether the C sources have been altered or not. The disadvantage is that if the C sources are large, there can be a noticable delay each time the model is updated, simulated or built.

The S-function can be setup with a callback function as follows:

  1. Right-click on the S-function block and choose Block Properties.

  2. Then choose InitFcn and enter the following commands:

    cd ddd
    mex xx_code_wrapper.c
    cd ..

    where ddd is replaced with the name of the data dictionary directory.