This is an example project about generating, verifying and integrating C/C++ code using MATLAB and CMake.
- MATLAB is a programming and numeric computing platform with powerful data analysis and graphics tools.
- C is a general-purpose, procedural programming language with little hardware abstraction. It is efficient, portable and commonly used in embedded systems.
- C++ is almost a superset of C. It is one of the highest-level programming languages that can still provide deterministic execution time.
-
Set up your project directory as shown
<Project Name> ├─📂docs ├─📂include ├─📂matlab ├─📂src ├─📂tests │ └─📂matlab │ └─ run_all_tests.m ├─ CMakeLists.txt └─ README.md
File/Folder Explanation /docs Documentation files (.md, .docx, .txt...) /include Header files (.h, .hpp, .hxx, ...) /matlab MATLAB scripts, prototypes, derivations (.m, .slx, ...) /src Source files (.c, .cpp, .cxx, ...) /tests Test files (.c, .cpp, .cxx, ...) /tests/matlab MATLAB test scripts (.m, ...) run_all_tests.m MATLAB script to call all MATLAB test scripts CMakeLists.txt Describes the build process, read by CMake README.md Summary of the project -
Start with your mathematical derivations and document them in
/docs
, e.g. derivation.ipynb. -
Prototype your derivations in MATLAB in
/matlab
, e.g. filter_1st_order.m. -
Write MATLAB test scripts for your prototypes in
/tests/matlab
to verify them. -
Code your project based on the prototypes, this step may include C/C++ code generation from MATLAB code. Do whichever is appropriate and convenient. Problem parameters known at compile time should be written in a separate header file, e.g. Parameters.hpp.
-
Write your unit tests in
/tests
. These unit tests should be automated as much as possible, but for verification and debug purposes a human may need to look at some plots. For this task read/write data to disk, and plot the data using MATLAB. It is important to share the problem parameters with the MATLAB test scripts. This can be achieved by including a step in the build instructions to write them to simple MATLAB-readable files, e.g. ParametersToFile.cpp. -
Update the MATLAB test scripts to incorporate the unit tests if desired, e.g. test_filter.m.
- Configure the project using CMake.
- Build the project and run CTest tests.
- Run the MATLAB script
run_all_tests.m
.
For help, see the How to compile? section.
- Prototype in MATLAB
- Code and implement in C/C++
- Verify in MATLAB
Unit testing is highly encouraged. Here is a good introduction to unit testing. The tester may or may not be the original programmer or a programmer.
MATLAB
┌──────────────────────┐
│ 1) │
│ ┌─────────┐ │
│ │Prototype│◄────┐ │
│ └────┬────┘ │ │
│ │ ┌──┴──┐ │
│ │ │Debug│ │
│ ▼ └──┬──┘ │
│ ┌───────┐ │ │
┌──┼─►│Verify ├──────┘ │
│ │ └───────┘ │
│ └──────────────────────┘
│
│ C/C++
│ ┌──────────────────────┐
│ │ 2) │
│ │ ┌─────┐ │
│ │ │Write│◄────┐ │
│ │ └──┬──┘ ┌──┴──┐ │
│ │ │ │Debug│ │
│ │ ▼ └──┬──┘ │
│ │ ┌───────┐ │ │
├──┼───┤Compile│────┘ │
│ │ └───┬───┘ │
│ └───────┼──────────────┘
│ │
│ Embedded│system
│ ┌───────┼──────────────┐
│ │ 3) ▼ │
│ │ ┌──────────┐ │
└──┼──┤Experiment│ │
│ └──────────┘ │
└──────────────────────┘
The workflow is split into three environments,
- MATLAB
- C/C++: Editor/IDE and build tools
- Embedded system: Microcontroller
These environments have different levels of flexibility and portability. The main objective of this workflow is to play the strengths of each environment. MATLAB is very powerful for prototyping algorithms and verifying data, and so all verification should take place in MATLAB.
Verification means different things during different stages of development (i) In the prototyping stage it means prototypes are compared against existing data and solutions (e.g. analytical solutions), and (ii) in the coding and implementation stage it means the results produced meet expectations. You should worry about ideas while sketching and worry about the technique when drawing.
Verifying results from C/C++ and the embedded system in MATLAB is not a substitute for unit testing in their respective environments. All three environments should have their own (automated) unit testing routines whenever possible, including MATLAB prototypes. The MATLAB prototype can guide unit testing in other environments.
These instructions are for using Visual Studio Code.
- Install VS Code
- Install the following extensions for VS Code:
- C/C++
- CMake Tools (You may follow these instructions)
- Install CMake and add to path during installation.
- For Windows, install Msys2. (You may follow these instructions) and add
C:\msys64\mingw64\bin
to path. Open an Msys2 terminal type, inpacman -Syu
andpacman -S --needed base-devel mingw-w64-x86_64-toolchain
. For other platforms, make sure gcc is installed. - Verify g++ installation by typing
g++ --version
in an Msys2 terminal. It should display the current version. - Open the project root folder in VS Code (where the top
CMakeLists.txt
lives). By default CMake Tools will configure the project for you, creating abuild
folder. You may build and run tests using the task bar on the bottom of your screen. - If CMake tools fails to find prefered generator, addd
"cmake.mingwSearchDirs": [
"C:\\mingw-w64\\mingw64\\bin"
],
"cmake.generator": "MinGW Makefiles"
to your VS Code settings (or your absolute path to mingw64 bin directory).
You will need a C++ compiler to compile .cpp
files. You can use VS Code with gcc for this task.
Once the C/C++ code is verified, it can easily be integrated to any environments. For example, it can be wrapped in Python for easy installation and visualization, such as graphical user interfaces. This can potentially extend our verification capabilities by allowing easy communication between different devices over different protocols.
- The prototype and the C/C++ implementation may diverge over time. If this happens, since the C/C++ implementation must be verified, this may necessitate updating the prototype or adding new MATLAB code for comparison purposes.
- MATLAB may not be available everywhere. Whenever possible the unit tests should work independently of the MATLAB testing scripts.
This work was supported by the National Science Foundation DCSD Grant (No. 2029181).