real-time matlab/simulink code generation

real-time matlab code generation

backgroud

Python and Linux vs Matlab and Windows, I prefer the front. but as a teamwork, I have to understand how matlab/Simulink code generation works, especially with real-time model.

previously named as Real-Time workshop(rtw).

real time model data structure

access rtModel data by using a set of macros analogous to the ssSetxxx and ssGetxxx macros that S-functions use to access SimStruct data, including noninlined S-functions compiled by the code generator.

You need to use the set of macros rtmGetxxx and rtmSetxxx to access the real-time model data structure. The rtModel is an optimized data structure that replaces SimStruct as the top level data structure for a model. The rtmGetxxx and rtmSetxxx macros are used in the generated code as well as from the main.c or main.cpp module.

Usage of rtmGetxxx and rtmSetxxx macros is the same as for the ssSetxxx and ssGetxxx versions, except that you replace SimStruct S by real-time model data structure rtM.

rtm macro description
rtmGetdX(rtm) get the derivatives of block continous states
rtmGetNumSampleTimes(RT_MDL rtM) Get the number of sample times that a block has
rtmGetSampleTime(RT_MDL rtM, int TID) Get task sample time
rtmGetStepSize(RT_MDL) Return the fundamental step size of the model
rtmGetT(RT_MDL,t) Get the current simulation time
rtmGetErrorStatus(rtm) Get the current error status

code generation to used externally :

1) Install the Real-Time Workshop (RTW) Toolbox for MATLAB;

2) Create the Simulink Model and Prepare it for autocoding;

3) Correctly configure the RTW options and include a *.tcl file;

4) Build any S-Functions of the model;

5) Build the model (generate autocode including makefile);

6) Tune up the makefile with any missing options/libraries/files;

7) Integrate autocoded model in RTEMS using the wrapper.

ert_main()

the following is a common sample of real-time model generated C code.

1
2
3
4
5
6
7
8
9
10
11
rt_OneStep(void){
simulation_custom_step() ;
}
main(){
simulation_initialize();
while(rtmGetErrorStatus(xx_M) == (NULL)){
rt_OneStep();
}
simulation_terminate();
return 0;

if no time interupt setting up, there is a Warning: The simulation will run forever. Generated ERT main won’t simulate model step behavior. To change this behavior select the ‘MAT-file logging’ option.

from real-time Matlab/Simulink model to C/C++ code, we need manually set the while-loop break statement. for example, we can run 100 times or based on some event-trigger.

Timing

1
2
3
4
5
6
7
8
struct {
uint16_T clockTick1; //base rate counter (5s)
struct {
uint16_T TID[2];
} TaskCounters; //subtask counter (0.02s)
} Timing;
currentTime = Timing.clockTick1 * 5.0 ;

absolute timer for sample time: [5.0s, 0.0s]. the resolution of this integer timer is 5.0, which is the step size of the task. so bascially, assuming to run one step need physcially 5s, but inside the module, each internal step is 0.02s.

if we run a test scenario with 20s, basically we have 4 clockTick1 and inside each clockTick1, we have 250 times internal steps.

a few modification

the following is a few modification based on the auto-generated C code:

  • redefine data structure

matlab coder use most C structure to package signals. in our adas model, most signals have similar inner items, so first I’d like to define a parent structre, then define all other adas signals using typedef:

1
2
3
4
typedef structure parent adas_sig1 ;
typedef structure parent adas_sig2 ;
typedef structure parent adas_sig3 ;
typedef structure parent adas_sig4 ;

with the parent struct, we can define one method to handle all adas signals.

  • add trigger model in rt_oneStep()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
checkTriggerSigs(&FunctionSignal, outputs_name);
int idx = 0;
for(; idx<outputs_name.size(); idx++){
if ( outputs_name[idx] == "adas_sig1") {
double *vals = gd1_struc_2arr(adas_ig1) ;
outputs_data.push_back(als);
}
else if( outputs_name[idx] == "adas_sig2") {
double *vals = gd1_struc_2arr(adas_sig2) ;
outputs_data.push_back(vals);
}
// ws msg send model
  • add sim_time to break the loop
1
2
3
4
5
real_T sim_time = 5.0 ;
fflush((NULL));
while (rtmGetErrorStatus(OpenLoopSimulation_M) == (NULL) && (Timing.clockTick1) * 5.0 <= sim_time) {
rt_OneStep();
}

in summary

the work above is the core modifcation to make real-time matlab/simulink model with trigger model translated to C/C++ code, which can be integrated in massively adas test pipeline.

refer

matlab code generation from rtems

the joy of generating C code from MATLAB

matlab coder introduction

matlab code doc

real-time model data structure

generate code from rate-based model

schedule a subsystem multiple times in a single step