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:
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 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
Tags
| Date | 2026-05-22 |
| Type de logiciel | Logiciels d’implémentation |
| Produit | RTI (Real-Time Interface) |
| Type d’information | Foire Aux Questions (FAQ) |
| Catégorie d’information | Phase de débogage |
| Keywords | debug, user Code file, S-Function, [model].c file, Data Store Memory Block, msg_info_printf(), msg_info_set(), global variables, ExportedGlobal |