C code generation: memory allocation for reference model in multi-instance mode

6 views (last 30 days)
I am generating c code for model reference hierarchy using Embedded Coder.
There are reference models which are called multiple times from a parent model.
In the generated code, the block signals and block states data for each instance of reference model is accumulated in block states data of parent model creating a large structure(which causes compilation error).
I would like to have a single memory allocation(global) for this reference model data and reuse it for all instances.
I tried changing many settings related to code generation/optimization, but could not fix this.
Is there any method to achieve this?
/* Block states (default storage) for model 'ParentModel' */
typedef struct {
  MdlrefDW_ChildModel_T Instance1;
  MdlrefDW_ChildModel_T Instance2;
  MdlrefDW_ChildModel_T Instance3;
  ...
}DW_ParentModel_xxxx_T
ChildModel is having an image processing logic and MdlrefDW_ChildModel_T is having a size of 200MB.
So when the number of instances increases, size of final _DW structure increases significantly.

Answers (1)

Hassaan
Hassaan on 11 Jan 2024
In Simulink and especially with Embedded Coder for generating C code, handling large models with multiple referenced models can lead to the issues you're facing, where each instance of the referenced model is allocated its own memory. When a referenced model is used multiple times, this can cause the size of the generated code to grow significantly, potentially leading to compilation errors due to excessive memory consumption.
To handle this scenario, you can utilize the concept of reusable code for referenced models, which allows you to have a single copy of the data structures that are shared across multiple instances. Here's how you can approach this:
  1. Enable Reusable Code Generation: In the Simulink model configuration parameters, under the "Code Generation" > "Interface" section, there is an option for "Multi-instance code error diagnostic". Set this to "None" to allow multiple instances of a model to reuse the same code.
  2. Model Configuration Parameters: For the referenced model, go to the Model Configuration Parameters, and under the "Code Generation" > "Interface" section, set the "Code interface packaging" to "Reusable function". This tells the code generator to create a single set of data that can be used by all instances.
  3. Storage Classes: Define a custom storage class in the Embedded Coder Dictionary that specifies how code generator should handle the storage of model data. You can create a storage class that specifies the data should be stored in a global memory space.
  4. Manual Memory Management: If the above methods do not suffice, consider managing the memory manually. You can modify the generated code to allocate memory dynamically and use pointers to reference the same memory space from multiple instances of the referenced model.
  5. Use of Data Store Memory: You might explore using Data Store Memory blocks with global scope to define common data sections that can be accessed by different parts of the model hierarchy.
  6. Optimization Settings: In your Simulink model, explore the "Optimization" settings in the configuration parameters. You can experiment with settings such as "Signal storage reuse", "Buffer reuse", and "Data object storage reuse" to see if they can reduce the memory footprint.
  7. Consult MathWorks Support: Since memory issues can be quite complex and specific to your model structure, reaching out to MathWorks technical support would be advisable. They might offer specific solutions tailored to your use case, or provide best practices for large-scale model code generation.
Here is an example of how you might declare a global structure in your header file (manually edited post code-generation):
/* Global data for Child Model */
MdlrefDW_ChildModel_T Global_ChildModel_Data;
/* Block states (default storage) for model 'ParentModel' */
typedef struct {
  MdlrefDW_ChildModel_T *Instance1;
  MdlrefDW_ChildModel_T *Instance2;
  MdlrefDW_ChildModel_T *Instance3;
  ...
} DW_ParentModel_xxxx_T;
/* In your initialization code */
DW_ParentModel_xxxx_T ParentModel_DW;
ParentModel_DW.Instance1 = &Global_ChildModel_Data;
ParentModel_DW.Instance2 = &Global_ChildModel_Data;
ParentModel_DW.Instance3 = &Global_ChildModel_Data;
...
This manual approach requires you to manage memory assignments carefully and ensure that no conflicts occur due to the sharing of data structures.
The feasibility of the above solutions may depend on the specifics of your project and the versions of MATLAB/Simulink you are using.
---------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

Categories

Find more on Simulink Coder in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!