MATLAB: How can we ensure that the Outport function call in the generated code is present in a conditionally executed statement when merging ouputs from two runnables in Simulink R2016b

autosarcodeconditionallyEmbedded Coderexecutedgenerationmergertewrite

In the attached Autosar based Simulink model ("autosar_multirunnables_non_virtual_outports.slx"), both the inputs to the 'Merge' block which is located before the 'PPort_DE4' outport block are controlled by 'If Action Subsystems'. The above model is a modified version of the Simulink model used in this example – http://www.mathworks.com/help/ecoder/examples/autosar-code-generation-for-multiple-runnable-entities.html
The first input to the 'Merge' block is controlled by the 'If Action Subsystem' present in the runnable named – 'Runnable2_subsystem' and the second input to the 'Merge' block is controlled by another 'If Action Subsystem' present in the runnable named – 'Runnable3_subsystem'.
When we generate code from this model, we expect to see two function calls which write to the outport 'PPort_DE4' within an "if" conditional statement. But in the generated code we see the following – 
 
155 if (rtDWork.Output_DSTATE_d >= rtDWork.DiscreteTimeIntegrator_DSTATE) {
156 /* Outputs for IfAction SubSystem: '<S6>/If Action Subsystem' incorporates:
157 * ActionPort: '<S9>/Action Port'
158 */
159 rtB.In1_l = rtDWork.Output_DSTATE_d;
160
161 /* End of Outputs for SubSystem: '<S6>/If Action Subsystem' */
162 }
163
164 /* End of If: '<S6>/If' */
165 /* End of Outputs for SubSystem: '<S2>/ExplicitWrite' */
166
167 /* Outport: '<Root>/PPort_DE4' incorporates:
168 * SignalConversion: '<S2>/OutportBufferForSubtracter'
169 */
170 Rte_IWrite_Runnable2_PPort_DE4(rtB.In1_l);
The "Rte_IWrite_Runnable2_PPort_DE4(rtB.In1_l);"  function call corresponding to the write from Runnable2 is not present in the "if" conditional statement. Similarly the write function call corresponding to 'Runnable3' is as follows – 
 
245 if (rtDWork.Output_DSTATE >= rtb_TmpSignalConversionAtIn1Out * tmp[0]) {
246 /* Outputs for IfAction SubSystem: '<S11>/If Action Subsystem' incorporates:
247 * ActionPort: '<S14>/Action Port'
248 */
249 rtB.In1 = rtDWork.Output_DSTATE;
250
251 /* End of Outputs for SubSystem: '<S11>/If Action Subsystem' */
252 }
253
254 /* End of If: '<S11>/If' */
255 /* End of Outputs for SubSystem: '<S3>/ExplicitWrite' */
256
257 /* Outport: '<Root>/PPort_DE4' incorporates:
258 * SignalConversion: '<S3>/OutportBufferForMultiplier'
259 */
260 Rte_IWrite_Runnable3_PPort_DE4(rtB.In1);
How can we ensure that both the Rte_IWrite statements are present within the conditional statements?
 

Best Answer

This can be done by setting all the outports starting from the 'If Action SubSystems' to the 'Merge' block as virtual. This can be done in the following manner - 
1. Starting from the '/Runnable2_subsystem/ExplicitWrite/If Action Subsystem', double click on the 'Out1' outport block and check the 'Ensure outport is virtual' option in the 'Main' tab.
2. Following along this signals path, set the '/Runnable2_subsystem/Subtracter' outport as virtual using the above procedure.
3. Similarly starting from the 'Out1' outport in the '/Runnable3_subsystem/ExplicitWrite/If Action Subsystem' we set the outports along the other signal to the merge block as virtual.
4. We also set the '/Runnable3_subsystem/Multiplier' outport as virtual.
Please find the attached updated Simulink model ("autosar_multirunnables_virtual_outports.slx"). If we generate the code for this model, we can see that the *Rte_IWrite** function calls are present within conditional statements as follows - 
The call corresponding to the Runnable2 write - 
161 if (rtDWork.Output_DSTATE_d >= rtb_Subtract) {
162 /* Outputs for IfAction SubSystem: '<S6>/If Action Subsystem' incorporates:
163 * ActionPort: '<S9>/Action Port'
164 */
165 /* Outport: '<Root>/PPort_DE4' incorporates:
166 * DataTypeConversion: '<S2>/Data Type Conversion'
167 * Inport: '<S9>/In1'
168 */
169 Rte_IWrite_Runnable2_PPort_DE4(rtDWork.Output_DSTATE_d);
170
171 /* End of Outputs for SubSystem: '<S6>/If Action Subsystem' */
172 }
The call corresponding to the Runnable3 write - 
 
236 if (rtDWork.Output_DSTATE >= rtb_TmpSignalConversionAtIn1Out * tmp[0]) {
237 /* Outputs for IfAction SubSystem: '<S11>/If Action Subsystem' incorporates:
238 * ActionPort: '<S14>/Action Port'
239 */
240 /* Outport: '<Root>/PPort_DE4' incorporates:
241 * DataTypeConversion: '<S3>/Data Type Conversion'
242 * Inport: '<S14>/In1'
243 */
244 Rte_IWrite_Runnable3_PPort_DE4(rtDWork.Output_DSTATE);
245
246 /* End of Outputs for SubSystem: '<S11>/If Action Subsystem' */
247 }
Please note that the checkbox option ('Ensure outport is virtual') in the 'Outport' block was introduced in Simulink R2016b. Therefore, this workaround can be used to generate code as shown above from Simulink version R2016b.