How does the simulink generated code get the external inputs?

24 views (last 30 days)
Hello,
I have a Simulink model that has some root level inports and outports. I did C code generation for the same using Simulink coder. I am unable to figure out how the generated code accesses the data which comes through the inports, as all the functions defined in model.c file, namely step(), initialize() and terminate() are of void void type. Where in the generated code is there a statement, through which the data coming through the inports can be accessed by the actual code? Also, I did not get any grt_main.c file after code generation. Does it mean that something might have went wrong while code generation?
Thanks
  1 Comment
Joshua O'Reilly
Joshua O'Reilly on 26 Aug 2019
Edited: Joshua O'Reilly on 26 Aug 2019
Hi Shilpesh, this is super late, but I'm running into the same issue and slowly making headway.
If you open the header file for the model files (in my case, the Simulink model was called raspberry_pi_deploy.slx, and so the header file is called raspberry_pi_deploy.h), you'll see that two structs are defined; one for your inports and one for your outports.
// External inputs (root inport signals with default storage)
typedef struct {
real_T thetaDesired; // '<Root>/thetaDesired'
real_T controllerGains[2]; // '<Root>/controllerGains'
} ExtU;
And
// External outputs (root outports fed by signals with default storage)
typedef struct {
real_T dSs; // '<Root>/dSs'
} ExtY;
With the class declaration
// Class declaration for model raspberry_pi_deploy
class raspberry_pi_deployModelClass {
// public data and function members
public:
// External inputs
ExtU rtU;
// External outputs
ExtY rtY;
// model initialize function
void initialize();
// model step function
void step();
// Constructor
raspberry_pi_deployModelClass();
// Destructor
~raspberry_pi_deployModelClass();
// Real-Time Model get method
RT_MODEL * getRTM();
// private data and function members
private:
// Block signals and states
DW rtDW;
// Real-Time Model
RT_MODEL rtM;
};
If you navigate to your main file (ert_main.cpp), you'll see that, in the main method, the object's public methods are called using dot notation:
rtObj.initialize();
My code also has a method called rt_OneStep() that explicitely indicates where to set and get model inputs and outputs.I figure that, since your inport and output variables are public class properties, you can also modify them by callingrtObj.rtU.thetaDesired = 15;
void rt_OneStep(void)
{
static boolean_T OverrunFlag = false;
// Disable interrupts here
// Check for overrun
if (OverrunFlag) {
rtmSetErrorStatus(rtObj.getRTM(), "Overrun");
return;
}
OverrunFlag = true;
// Save FPU context here (if necessary)
// Re-enable timer or interrupt here
// Set model inputs here
//--------------------------------------
// MY INPUTS ARE HERE !!!!!!!!
rtObj.rtU.controllerGains[0] = 1;
rtObj.rtU.controllerGains[1] = 0.5;
//--------------------------------------
// Step the model
rtObj.step();
// Get model outputs here
//--------------------------------------
// MY OUTPUTS ARE HERE !!!!!!!!
someVar = rtObj.rtY.dSs;
//--------------------------------------
// Indicate task complete
OverrunFlag = false;
// Disable interrupts here
// Restore FPU context here (if necessary)
// Enable interrupts here
}
I have very little C/C++ experience so it's entirely possible that this is the wrong approach, but if you're trying to figure out the fundamentals of interacting with inport and output values, hopefully this helped a bit :)
I'll add more information here as I make headway with my own model.
EDIT: I realized you're generating C code, not C++; hopefully this is still sorta applicable. I do find it weird you didn't get a grt_main.c file, since I got a ert_main.cpp one.

Sign in to comment.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!