Use Signal Conversion or Bias Blocks to Resolve Issues with Reusable Code Generation
When you configure subsystems to generate a shared function, the code generator determines whether the subsystems are eligible for reusable code generation. Subsystems must have equal checksums to be able to generate a shared function. However, reusable code generation is an optimization feature that is not guaranteed. Even if subsystems have equal checksums, the code generator might not generate reusable code due to how the subsystems relate to other blocks in the model or model reference hierarchy, such as if a subsystem connects to a root Inport or Outport block.
If your model contains subsystems for which you expect the code generator to generate a shared function but the code generator generates separate functions, you can use Signal Conversion or Bias blocks to isolate those subsystems from other parts of the model or model reference hierarchy. A Signal Conversion or Bias block between a subsystem and another block can prevent the code generator from detecting a relationship between the subsystem and that block that causes the code generator to generate separate functions.
Use Bias blocks to isolate subsystems that contain a Merge block that has initial conditions. In other circumstances, use Signal Conversion blocks.
Inspect Model Hierarchy
Consider this top model.
open_system('ex_codeReuseTopModel')
The top model references this referenced model.
open_system('ex_codeReuseThreeSubsys')
The referenced model has the Default parameter behavior model configuration parameter set to Inlined and contains three instances of an atomic subsystem. The first and last subsystem instances are connected to the root Inport and Outport block of the referenced model, respectively. Each subsystem instance has the Function packaging subsystem block parameter set to Reusable function.
Generate and Inspect Code
Press Ctrl+B to generate code for the top model.
evalc('slbuild(''ex_codeReuseTopModel'')');Inspect the generated file ex_codeReuseThreeSubsys.c.
file = fullfile('slprj/grt/ex_codeReuseThreeSubsys','ex_codeReuseThreeSubsys.c'); coder.example.extractLines(file,'/* Output and update for atomic system: ', ... '/* Output and update for referenced model',1,0);
/* Output and update for atomic system: '<Root>/Subsystem 1' */
void ex_codeReuseThreeSubsys_Subsystem1(const real_T *rtu_In1,
B_Subsystem1_ex_codeReuseThreeSubsys_T *localB)
{
/* Gain: '<S1>/Gain' */
localB->Gain = 3.0 * *rtu_In1;
}
/* Output and update for atomic system: '<Root>/Subsystem 2' */
void ex_codeReuseThreeSubsys_Subsystem2(real_T rtu_In1,
B_Subsystem2_ex_codeReuseThreeSubsys_T *localB)
{
/* Gain: '<S2>/Gain' */
localB->Gain = 3.0 * rtu_In1;
}
/* Output and update for atomic system: '<Root>/Subsystem 3' */
void ex_codeReuseThreeSubsys_Subsystem3(real_T rtu_In1, real_T *rty_Out1)
{
/* Gain: '<S3>/Gain' */
*rty_Out1 = 3.0 * rtu_In1;
}
Although the referenced model seems to be configured for subsystem code reuse, the code generator produces a separate function signature for each subsystem instance instead of a single reusable function. Because the subsystems do not contain Merge blocks that have initial conditions, you can use Signal Conversion blocks to isolate the referenced model.
Modify Referenced Model and Regenerate Code
Consider this model, which is similar to ex_codeReuseThreeSubsys but contains Signal Conversion blocks before and after the subsystem instances.
open_system('ex_codeReuseSubsysSigConvert')
Modify the top model to reference this model.
set_param('ex_codeReuseTopModel/Model','ModelFile','ex_codeReuseSubsysSigConvert')
Generate code for the top model and inspect ex_codeReuseThreeSubsys.c.
evalc('slbuild(''ex_codeReuseTopModel'')'); file = fullfile('slprj/grt/ex_codeReuseSubsysSigConvert','ex_codeReuseSubsysSigConvert.c'); coder.example.extractLines(file,'void ex_codeReuseSubsysSigConvert_Subsystem1', ... '/* Output and update for referenced model',1,0);
void ex_codeReuseSubsysSigConvert_Subsystem1(real_T rtu_In1,
B_Subsystem1_ex_codeReuseSubsysSigConvert_T *localB,
P_Subsystem1_ex_codeReuseSubsysSigConvert_T *localP)
{
/* Gain: '<S1>/Gain' */
localB->Gain = localP->Gain_Gain * rtu_In1;
}
The generated code contains a single reusable function for the reusable subsystems. This means that the subsystem instances do not have differences among themselves that are responsible for the generation of separate functions. Instead, the problem is related to the relationship between the top model and referenced model. To continue generating reusable code, leave the Signal Conversion blocks in the model.
If your model still generates separate functions after you isolate subsystems with Signal Conversion or Bias blocks, there might be differences between the subsystem instances. For information about how to programmatically identify differences between subsystems, see Compare Checksums to Determine Why Generated Code Is Not Reused.