Main Content

External Code Integration of Libraries and C/C++ Code with Simulink Real-Time Models

Considerations for Integrating Third-Party Libraries and External Code into Simulink Real-Time

Developers who integrate C/C++ code with Simulink Real-Time applications notice some differences when they migrate the code that they integrated with Simulink Real-Time applications from previous releases to R2020b and later releases. These differences include:

  • In release R2020a and previous releases, the On-Time RTOS on the target computer shared some libraries and system calls with Windows®. In release R2020b and later releases, the QNX® Neutrino® RTOS on the target computer does not share libraries or system calls specific to Windows.

  • In release R2020a and previous releases, developers could use Microsoft® Visual Studio® to compile libraries to integrate with Simulink Real-Time applications. In release R2020b and later releases, you cannot use the Microsoft Visual Studio compiler for this purpose. You can configure Microsoft Visual Studio to use the QNX Neutrino compiler from the Simulink Real-Time target support package.

  • In R2020b and later releases, developers use cross-compiling to produce libraries on their development computer for deployment to their target computer.

Value of Upgrading Your C/C++ Code for Integration into Simulink Real-Time

By updating your C/C++ code for integration into your Simulink Real-Time application, you gain these benefits:

  • Leverage the QNX Neutrino 64-bit and POSIX® compatible RTOS.

  • Code directly in C++ or wrap your legacy C code.

  • Use the code editor of your choice.

    For instance, customizing Visual Studio Code with the source files and shipped QCC compiler from the Simulink Real-Time Target Support Package provides a similar experience to a full IDE.

  • Leverage the precompiled QNX Neutrino libraries and headers that are included in Simulink Real-Time to extend the functionality of your real-time application.

  • Integrate any C/C++ application based on modern build and package software such as CMake.

Approaches for C/C++ Code Integration into Simulink Real-Time

There are advantages and disadvantages to each of these external code integration approaches.

Approach 1: Directly Call C/C++ Code. In this approach, you ​use C Caller or C Function blocks in the model. For more information, see Integrate External C/C++ Code Using C Function Blocks.​

Approach 2: Build, link, and use static libraries (.a files)​

  • Advantages​: All required files are packed in the real-time application MLDATX file. In this approach, ​there is no need to install libraries on the target. And, this approach lets you ​protect your intellectual property.​

  • Disadvantages​: This approach is non-modular. A change in the library requires rebuilding the whole real-time application​. Also, this approach tends to produce larger real-time application MLDATX files.​

Approach 3: Build, deploy and use shared objects (.so files)​

  • Advantages​: This approach is modular. You can build the real-time application and shared object independently​. Also, this approach tends to produce smaller real-time application MLDATX files. And this approach lets you protect your intellectual property.​

  • Disadvantages: ​In this approach, you need to access the target computer file system before running the real-time application and install (copy) the shared objects​ to any of the common lib paths on the target computers.

Build Libraries from Source Code for Simulink Real-Time

To integrate external code in a real-time application, the most flexible approaches are to build static libraries or shared objects from source code.

  • The library build workflow is similar to the workflow used by most developers for release R2020a and previous releases. In those releases, the library build workflow for the target computer On-Time RTOS produced static libraries built with Microsoft Visual Studio and produced .lib files.

  • You achieve better usability when working with complex C++ projects that have many dependencies and source code files.

  • S-functions offer better granularity when handling third-party libraries in Simulink. S-functions enable the flexibility to use the same S-function source code with different platforms, including simulation on the desktop in different operating systems. The S-functions are deployed and function in real-time on a target computer.

Cross-compiling is compiling a library for a target operating system (for example, QNX Neutrino RTOS) on a development operating system (for example, Windows). Some cross-compiling considerations for Simulink Real-Time are:

  • Choice of development environment. Many modern C++ projects use the CMake build environment. For more information, see the CMake website.

  • Extensibility of development environment. For example, it is a common practice to extend most common CMake support for the QNX Neutrino RTOS by leveraging similarities with the UNIX® OS and its POSIX compatibility.

  • In your libraries, save cross-compiling libraries, including dependencies that might be already included in the Simulink Real-Time Target Support Package. These libraries can be linked to other C++ projects.

The suggested workflow for integration of complex C++ applications into Simulink Real-Time is:

  1. Start from a C++ project with CMake as the build environment.​

  2. Set the dependencies, such as headers and libraries, in your Simulink model.​

  3. On the development computer, cross-compile libraries for the QNX Neutrino RTOS on the target computer.​

  4. Create an S-function, for instance using the S-function Builder block or a handwritten C-MEX S-function, as the main function that calls the C++ functions defined in the header files and implemented in the compiled libraries for the QNX Neutrino RTOS​.

  5. Build the real-time application. ​

  6. By using SSH or FTP, copy your cross-compiled libraries to a location on the target computer where they can be found and loaded at run time. The recommended locations are /lib, /usr/lib, or /usr/local/lib.

  7. Load and run the real-time application.

External Code Integration for S-Functions and Simulink Real-Time

When you include static libraries or shared objects in S-functions for external code integration with a real-time application, there are some tips for your development.

When building from Simulink:

  • Use rtwmakecfg.m and makeInfo object to map libraries and header files. For more information, see Use rtwmakecfg.m API to Customize Generated Makefiles.

    function makeInfo = rtwmakecfg​
    proj = currentProject;​
    rootPath = proj.RootFolder;​
    makeInfo.linkLibsObjs = {};​
    sysTarget = get_param(bdroot, 'RTWSystemTargetFile');​
    switch sysTarget​
        case 'slrealtime.tlc'​
            makeInfo.includePath = '<includePath>';​
            makeInfo.linkLibsObjs{end+1} = '<libraryPath>';​
            error('No rtwmakecfg found for %s target file', sysTarget);​
  • Enable linking for different target files.

  • Use macros, such as SIMULINK_REAL_TIME, in your source code to add lines at compile time for real-time simulation. SIMULINK_REAL_TIME is useful to wrap the LOG function calls.

When cross-compiling, use macros such as __unix__ and __QNXNTO__ in your source code to add lines at compile time.

Hello World! Example External Code Integration for Simulink Real-Time

This example shows how to use an S-Function Builder block for external code integration. The example adds a hello message to the system log.

Before running this example, install the Simulink Real-Time Target Support Package. The support package includes the tools that compile the code that runs on the target computer.

Open the Model

Use the Open Model button to open the slrt_ex_helloworld_sfunbuilder model.


Open the S-Function Block

Double-click the helloworld-sfun S-Function block. The S-Function Builder opens and displays the S-function code.

/* Includes_BEGIN */
#include "slrt_log.hpp"
/* Includes_END */
/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */
void helloworld_sfun_Start_wrapper(SimStruct *S)
/* Start_BEGIN */
/* Start_END */
void helloworld_sfun_Outputs_wrapper(const real_T *u0,
                                     real_T *y0,
                                     SimStruct *S)
/* Output_BEGIN */
// Create custom message
static char hellomsg[100];
sprintf(hellomsg,"Hello World! t=%f \n",*u0);
// Use macros for platform dependent code
// Generic platform independent code
*y0 = *u0;
/* Output_END */
void helloworld_sfun_Terminate_wrapper(SimStruct *S)
/* Terminate_BEGIN */
 * Custom Terminate code goes here.
/* Terminate_END */

Build Model and Run Real-Time Application

Before building the model, you can run the model on your desktop and view the output message in the Simulink Real-Time system log viewer.

When you are ready to build the model, on the Simulink Editor Real-Time tab, connect to the target computer and click Run on Target. Or, in the MATLAB Command Window, type:

tg = slrealtime;
model = 'slrt_ex_helloworld_sfunbuilder';

View Message in Status Log

Open the target computer status log and view the Hello World! message. On the Simulink Editor Real-Time tab, select Prepare > SLRT Explorer. Then, select the System Log Viewer tab. Or, in the MATLAB Command Window, type:


The viewer shows the Hello World! messages in the system log.

Close All Files


Additional C/C++ Project for Simulink Real-Time

The eCAL Toolbox for Simulink project on MathWorks GitHub shows complete external code integration with Simulink Real-Time, including S-function wrappers, rtwmakecfg customization, and shared object compilation. You also can simulate this example on your development computer.

Related Topics

External Websites