MATLAB: Embedded Coder providing incompatible, non-reusable code.

Embedded Coderreentrantreusable codesimulink

I'm trying to move from MATLAB R2018b to R2020a (and then R2020b). However, some models are no longer generating the same, reentrant code as they were before.
In R2018b, the following reusable code was generated (copied from the in-application help, of which a screenshot will is attached):
/* Real-time Model Data Structure */
struct tag_RTM_rtwdemo_roll_T {
const char_T *errorStatus;
B_rtwdemo_roll_T *blockIO;
P_rtwdemo_roll_T *defaultParam;
ExtU_rtwdemo_roll_T *inputs;
ExtY_rtwdemo_roll_T *outputs;
boolean_T paramIsMalloced;
DW_rtwdemo_roll_T *dwork;
};
Note in the above, that defaultParam was a member in the Model data structure. This allows different instances of this model to run with the correct, tuned parameters.
Newer code makes the parameters independent of the model instance. This means that tuning parameters are shared between unrelated code execution instances. The new documentation now matches the new behavior — https://www.mathworks.com/help/rtw/ug/how-generated-code-stores-internal-signal-state-and-parameter-data.html.
How can I keep the original behaviors and migrate to R2020a, which I believe was correct? Is there an explanation for why this was changed?

Best Answer

Hi,
There are two questions here, one technical (How can I get the same behaviour as before?) and one more "philosophical" (Why did it change?)
So for the first question, I think that one way to have the desired code is to define the parameter as a model argument with a non-auto storage class to have the same behaviour as before (having the parameter as part of the data structure)
To do that, you would need to do the following
  1. the parameter must be in the model workspace (not in the base workspace or a data dictionary)
  2. the parameter must be a model argument
  3. the parameter must define use a storage class not equal to "auto" ("Model default" for example)
For the second question, I think without being certain that I have an explanation. So this is going to be a little bit of speculation (but I can probably ask internally to confirm this), I think that it's more "consistent" with Simulink/MATLAB semantic in this way. When you run a simulation in Simulink, if you have a parameter that comes from the base workspace, it can only have one value at a time, even if you have multiple instances of the model. Which translate in the generated code (since 2019a I think) in one unique global variable, even for reusable function interface.
What you want is to have multiple values for multiple instances of the generated code, which match Model Arguments when you think in Simulink term. (They allow each instance of the model to have separate values)
In term of documentation, this change in behaviour was documented in the release notes of R2019a, under the title "Model argument support for top models". In particular:
Compatibility Considerations
Previously, you accessed parameter data in the top model through a pointer in the real-time model. If you generated code that used the reusable code format, you could define different parameter values for each instance of a top model [your behaviour]. You defined these different values by setting the pointer to different memory with different sets of parameter values. In R2019a, for multi-instance top models and top models that use a malloc memory model, parameter data in the top model is declared as a standalone global variable. For C++ code generation, the parameter data is a static member of the model class. To define different parameter values for each instance of a top model, you must configure model arguments in the same way that you configure model arguments for referenced models. Define the parameter in the model workspace then, in the Model Data Editor, Property Inspector, or Model Explorer, select the Argument check box. [the current pattern to obtain the previous behaviour]