FAQ 257: Debugging a C-Coded S-Function or the Generated Code 

Question

How can I debug the S-function source code or user code?

Solution

Writing information to the dSPACE Log File:

Writing Information to the dSPACE Log File


By means of the RTLib functions msg_info_set() and msg_info_printf(), messages can be written from the real-time application to the dSPACE.log file . These messages also appear in the LOG viewers of ControlDesk and the WebInterface.


The steps described below require at least basic knowledge of programming in C.


To write to the dSPACE.log file, insert the call of the function into the source code you want to debug. This can either be an S-function (for RTI systems and SCALEXIO systems) or user code (only for RTI systems: file <model>_usr.c in the working directory).

 

  • Write a simple text (test point)
      msg_info_set(MSG_SM_USER, <msg_no>, “<msg>”)
      à msg_info_set(MSG_SM_USER, 1, “Reached location XY”)
  • Write the value of a variable
      msg_info_printf(MSG_SM_USER, <msg_no>, “<format>”, arg1, arg2,…)
   à msg_info_printf(MSG_SM_USER, 2, “Value of nTemp %d”, nTemp)

           msg_info_printf() accepts the same format specifiers as the standard ANSI C routine printf().
 

After you modified the C code, it must be compiled again and linked to the real-time application.

When using RTI platforms, you should start the build process from the MATLAB Command Window.
 
For messages from an S-function to be written to the dSPACE log, certain header files from dSPACE must be included in the S-function. 

 

Example for RTI systems (exemplary S-function "My_SFunction"):

Below is an example (excerpt from S-Function Code) in which the output to the dSPACE Log is carried out:

#define S_FUNCTION_NAME  My_sFunction
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

#define MATLAB_MEX_FILE
#include "Btcenv.h"
#endif

Below is an example (excerpt from S-function code) in which the output to the dSPACE Log is carried out:

// ...

static void mdlOutputs(SimStruct *S, int_T tid)
{
    // ...

    #ifndef MATLAB_MEX_FILE
    msg_info_set(MSG_SM_USER, 1, "Message No. 1");
    msg_info_print(MSG_SM_USER, 2, "Message No. 2: %d", 1);
    #endif

    // ...
}
    // ...

The code used here leads to the following output in dSPACE Log on the MicroLabBox:

Example for SCALEXIO systems (exemplary S-function "My_SFunction"):

For SCALEXIO systems, include the DSMSG.h file from the <RCP_HIL_InstallationPath> \SCALEXIO\Include directory.

#define S_FUNCTION_NAME  My_sFunction
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

#ifndef MATLAB_MEX_FILE
#include "DSMsg.h"
#endif

Below is an example (excerpt from S-function code) in which the output to the dSPACE Log is carried out. The code used is identical to the example for the RTI platform:

//...

static void mdlOutputs(SimStruct *S, int_T tid)
{
    // ...

    #ifndef MATLAB_MEX_FILE
    msg_info_set(MSG_SM_USER, 1, "Message No. 1");
    msg_info_print(MSG_SM_USER, 2, "Message No. 2: %d", 1);
    #endif

    // ...
}

//...

The following applies to a SCALEXIO system:

Using Global Variables for Displaying Debug Data

Instead of, or in addition to, using the dSPACE.log file, global variables can be inserted into the code which are directly accessible with ControlDesk. This is, for example, necessary to observe (local) variables within an S-function’s source code. For this approach, the value from the local variable must be copied to the global variable.


The easiest way to create a global variable and the corresponding entry for this variable in the variable description file (TRC file) is to use a Data Store Memory block. Insert this block from the Simulink Signal Routing library.
It is important to set the storage class of the Data Store Memory block to ExportedGlobal.


Note that this method is not suitable for debugging code in the mdlStart() routine of an S-function.

 

The ExportedGlobal storage class must be selected for the Data Store Memory variable according to your MATLAB version so that a suitable global variable is generated in the model code.

Setting the storage classes may differ from one MATLAB version to another. For more information, please refer to MATLAB Help.

The procedure for creating and integrating global variables is illustrated below using an example for the MicroLabBox (RTI) and SCALEXIO systems.

In the first step, a global variable of the ExportedGlobal type is created in MATLAB − in this example, MATLAB version R2021b.

To do this, a variable − in this example "ReadMeVar" − is created in the Data Store Memory block:

The variable is assigned the value Simulink.Signal:

And the storage class ExportedGlobal:

Once the global variable has been used accordingly within the S-function, the value of this variable can be obtained within the running application via the output using a Data Store Read block in the Simulink model, e.g., in ControlDesk:

Above you can see an example of the use of the Data Store Read block in the Simulink model.

Above you can see an example of the value output in ControlDesk. Here, the variable receives the value from the S-function logic during a running application.

 

Example procedure for RTI systems (MicroLabBox)

After the build process, the corresponding global variable can be used in the C code with the name specified as the Data store name in the block dialog. In ControlDesk, it appears in the Date Stores variable description file group (TRC file group).

In the generated code <model>.c, or the user code file <model>_usr.c, the global variable can be used directly. In an S-function, however, the header file for the generated code must be included:

#include <model.h>

After building the application (SRTG + B), the global variable added in this way is created in the "Modelname.h" header file, as shown in the code excerpt from the header file used in the example here:


/* Exported States
 *
 * Note: Exported states are block states with an exported global
 * storage class designation. Code generation will declare the memory for these
 * states and exports their symbols.
 */

extern real_T ReadMeVar;        /* '<Root>/Data Store Memory' */

The header file is located in the build directory of the application.

The use of the global variable within the S-function therefore requires that the header file mentioned above is included, as shown in the example:


#define S_FUNCTION_NAME  My_sFunction
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

#ifndef MATLAB_MEX_FILE
#include "Btcenv.h"
#include "Modelname.h"
#endif

The following example shows an excerpt from the code in which the previously defined global variable is used:


//...

static void mdlOutputs(SimStruct *S, int_T tid)
{
    int_T  i;
    InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S, 0);
    real_T *y              = ssGetOutputPortRealSignal(S, 0);
    int_T  width           = ssGetOutputPortWidth(S, 0);

    #ifndef MATLAB_MEX_FILE
    msg_info_set(MSG_SM_USER, 1, "Message No. 1");
    msg_info_print(MSG_SM_USER, 2, "Message No. 2: %d", 1);

    for (i = 0; i < width; i++)
    {
        y[i]        = 3.0 * (*uPtrs[i]);
        ReadMeVar   = 3.0 * (*uPtrs[i]);
    }

    #endif
}

//...

 

Exemplary procedure for SCALEXIO systems

As for RTI based platforms, the Modelname.h header file must also be included in the S-function for SCALEXIO systems before the application is built.

The following example shows a code excerpt from an S-function:

#define S_FUNCTION_NAME  My_sFunction
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

#ifndef MATLAB_MEX_FILE
#include "DSMsg.h"
#include "Modelname.h"
#endif

How the previously defined global variable could be used is shown above in the example for RTI based platforms.

 

Related dSPACE HelpDesk Documents

•    rti_build in the RTI and RTI-MP Implementation Reference
•    msg_info_printf() in the processor or controller board related DS1XXX RTLib Reference
•    msg_info_set() in the processor or controller board related DS1XXX RTLib Reference

Related Topics

  • FAQ 255
    FAQ 255

    I want to implement a C-coded S-function for use with Real-Time Workshop/Simulink Coder/Real-Time Interface (RTI) and for Simulink simulations. Where can I find an S-function template and examples? Do I have to compile this S-function to a MEX DLL (...)

  • FAQ 239
    FAQ 239

    The real-time application was stopped due to an exception. How can I find out the reason for the exception? How can I debug the application?

  • FAQ 023
    FAQ 023

    I would like to know the execution time of a part of my model. How can I measure it?

Tags

Date 2026-05-22
소프트웨어 타입 Implementation Software
제품군 RTI (Real-Time Interface)
인포메이션 타입 FAQ
인포메이션 카테고리 Troubleshooting
Keywords debug, user Code file, S-Function, [model].c file, Data Store Memory Block, msg_info_printf(), msg_info_set(), global variables, ExportedGlobal

dSPACE direct 뉴스레터 서비스를 통해 최신 소식을 받아보세요.

dSPACE 뉴스레터 서비스를 통해 최신 use case 와 신규 솔루션 및 제품, 교육 및 이벤트에 대한 정보를 지속적으로 확인하세요. 여기에서 무료 로구독을 신청하세요.

Enable form call

At this point, an input form from Click Dimensions is integrated. This enables us to process your newsletter subscription. The form is currently hidden due to your privacy settings for our website.

External input form

By activating the input form, you consent to personal data being transmitted to Click Dimensions within the EU, in the USA, Canada or Australia. More on this in our privacy policy.