Importing and Testing Custom C/C++ Code
You can test custom C or C++ code by importing it into Simulink® using the Code Importer wizard in the Test Manager or API commands at the MATLAB® command line. You can perform unit testing to test a subset of your C code or integration testing to test your complete C or C++ code. When you import your code, the code importer:
Converts the C code functions to Simulink C Caller blocks and saves those blocks in a Simulink library
Creates an internal harness for each Simulink C Caller block
Generates a test file
For unit tests, the code importer additionally creates a sandbox to isolate the imported functions.
Import Code Using the Wizard or the API
To import and test custom C or C++ code using the Code Importer wizard, open the Test Manager and select New > Test for C/C++ Code. The wizard steps are shown in the Conduct Unit Testing on Imported Custom Code by Using the Wizard example. After you import the code using the wizard, the Test Browser pane of the Test Manager shows the generated test file, test suites, and test cases, and automatically fills the library model and test harness fields and coverage settings for each test case. You can customize the test cases in the Test Manager by adding inputs, assessments, links to requirements, or other options.
The Import Custom Code for Unit Testing Using API Commands example shows the classes and methods for importing code. The code importer sets the property values for the generated library, test file, test suites, test cases, and coverage. You can customize the test cases by using API commands to add inputs, assessments, links to requirements, or other options.
Before you run the test cases, either change the current folder to the folder that contains the generated artifacts or add the generated data dictionary to the path. Then run the test cases and view the coverage and other test results.
Code Importer Generated Artifacts
The code importer creates these artifacts:
A Simulink library with C Caller blocks for each imported custom code function.
An internal test harness for each C Caller block. For each generated harness, the solver is
FixedStepDiscrete
, and coverage is enabled.An MLDATX test file. The test file includes a test suite and test case for each C Caller block. The code importer also sets these coverage types:
Decision coverage
Condition coverage
MCDC coverage
Lookup table coverage
Signal range coverage
Coverage for Simulink Design Verifier blocks
Relational boundary coverage
Signal range coverage
Simulink data dictionary
Additionally, for unit tests only, the code importer creates:
A sandbox to isolate the functions being tested
Stubs, if any source files have undefined symbols
Limitations and Workarounds
These limitations and workarounds apply to using the custom C or C++ Code Importer.
General Limitations and Workarounds
For integration tests, if your code includes C++ functions, add wrappers around them to make them C-compatible before importing the functions into Simulink.
These C types, and functions with formal arguments that use these types, cannot be imported. Global variables that use these types are not exposed as ports on the C Caller block:
Structures with unions or pointer members
Functions with inputs that have more than one level of pointer indirection (for example,
>=**
)Functions that return a pointer
Types with names longer than 63 characters, and functions and variables that use those types
If your code has many global variables, use a Stateflow® chart instead of an Initialize Function block to set the variables to their initial values in your Simulink model.
If a header file or C or C++ file contains assembly code that is defined in the function body, the code importer does not import that function. This limitation applies only if the assembly code is not compatible with the host computer. To import the function,
For integration tests, replace the assembly code by using an
#ifdef
directive.For unit tests, the function is moved automatically to the
auto_stub.c
file with an empty body. To import the function into Simulink, manually stub the function inman_stub.c
.
For target-specific code, if the code accesses absolute memory addresses, comment out that code to prevent the simulation from failing.
Header Files
If the same header file is included multiple times and each inclusion is preceded by a different preprocessor directive (such as,
#define X 1
,#define X 2
), the code might not import correctly.If assembly code is defined in the header file, define a compatible macro by using an
#ifdef
directive. For example, if your code is:replace it with:#define XYZ(K,L) {\ asm("MOVLW " ___mkstr(K) ); \ asm("MOVLW " ___mkstr(L) ); \ }
Then, add#ifndef IS_SL_IMPORT #define XYZ(K,L) {\ asm("MOVLW " ___mkstr(K) ); \ asm("MOVLW " ___mkstr(L) ); \ } #else // a valid implementation #endif
IS_SL_IMPORT
to the list of defines when you import code.
Unit Tests
These limitations and workarounds apply only to unit tests.
Only C code is supported for importing.
If a source or header file contains a function definition that is included multiple times in the source file being imported, update the code so the function definition appears only once.
All included files, using
#include
, should be self-contained, that is, they compile on their own. Specifically, a header should have header guard and include all other headers that it needs.
See Also
sltest.CodeImporter
| sltest.CodeImporter.SandboxSettings
| createSandbox