Main Content

Control Cast Expressions in Generated Code

This example shows how to configure how the code generator specifies data type casts in the generated code.

In the Configuration Parameters dialog box, select Code Generation > Code Style. From the Casting modes drop-down list, three parameter options control how the code generator casts data types.

  • Nominal instructs the code generator to generate code that has minimal data type casting. When you do not have special data type information requirements, choose Nominal.

  • Standards Compliant instructs the code generator to cast data types to conform to MISRA™ standards when it generates code. The MISRA data type casting eliminates common MISRA standard violations, including address arithmetic and assignment. It reduces 10.1, 10.2, 10.3, and 10.4 violations. For more information, see MISRA C.

  • Explicit instructs the code generator to cast data type values explicitly when it generates code. You can see how a value is stored, which tells you how much memory space the code uses for the variable. The data type informs you how much precision is possible in calculations involving the variable.

Open the example model EmbeddedCoderIntro.

open_system('EmbeddedCoderIntro')

Enable Nominal Casting Mode and Generate Code

When you choose Nominal casting mode, the code generator does not create data type casts for variables in the generated code.

1. On the Code Generation > Code Style pane, from the Casting modes drop-down list, select Nominal.

set_param('EmbeddedCoderIntro', 'CastingMode', 'Nominal')

2. On the Code Generation > Report pane, select Create code generation report.

set_param('EmbeddedCoderIntro', 'GenerateReport', 'on')

3. On the Code Generation pane, select Generate Code Only.

set_param('EmbeddedCoderIntro','GenCodeOnly', 'on')

4. Click Apply.

5. In the model window, press Ctrl+B to generate code.

slbuild('EmbeddedCoderIntro')
### Starting build procedure for: EmbeddedCoderIntro
### Successful completion of code generation for: EmbeddedCoderIntro

Build Summary

Top model targets built:

Model               Action           Rebuild Reason                                    
=======================================================================================
EmbeddedCoderIntro  Code generated.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 19.586s

6. In the Code Generation report left pane, click EmbeddedCoderIntro.c to see the code.

file = fullfile('EmbeddedCoderIntro_ert_rtw','EmbeddedCoderIntro.c');
coder.example.extractLines(file,'/* Model step', '/* Model initialize',1,0);
/* Model step function */
void EmbeddedCoderIntro_step(void)
{
  boolean_T rtb_equal_to_count;

  /* RelationalOperator: '<Root>/RelOpt' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/LIMIT'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  rtb_equal_to_count = ((uint8_T)(rtDWork.X + 1U) != 16);

  /* Outputs for Triggered SubSystem: '<Root>/Amplifier' incorporates:
   *  TriggerPort: '<S1>/Trigger'
   */
  if (rtb_equal_to_count && (rtPrevZCSigState.Amplifier_Trig_ZCE != POS_ZCSIG))
  {
    /* Outport: '<Root>/Output' incorporates:
     *  Gain: '<S1>/Gain'
     *  Inport: '<Root>/Input'
     */
    rtY.Output = rtU.Input << 1;
  }

  rtPrevZCSigState.Amplifier_Trig_ZCE = rtb_equal_to_count;

  /* End of Outputs for SubSystem: '<Root>/Amplifier' */

  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/RESET'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  if (rtb_equal_to_count) {
    rtDWork.X++;
  } else {
    rtDWork.X = 0U;
  }

  /* End of Switch: '<Root>/Switch' */
}

Enable Standards Compliant Casting Mode and Generate Code

When you choose Standards Compliant casting mode, the code generator creates MISRA standards compliant data type casts for variables in the generated code.

1. On the Code Generation > Code Style pane, from the Casting modes drop-down list, select Standards Compliant.

set_param('EmbeddedCoderIntro', 'CastingMode', 'Standards')

2. On the Code Generation pane, click Apply.

3. In the model window, press Ctrl+B to generate code.

slbuild('EmbeddedCoderIntro')
### Starting build procedure for: EmbeddedCoderIntro
### Successful completion of code generation for: EmbeddedCoderIntro

Build Summary

Top model targets built:

Model               Action           Rebuild Reason                   
======================================================================
EmbeddedCoderIntro  Code generated.  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 16.924s

4. In the Code Generation report left pane, click EmbeddedCoderIntro.c to see the code.

file = fullfile('EmbeddedCoderIntro_ert_rtw','EmbeddedCoderIntro.c');
coder.example.extractLines(file,'/* Model step', '/* Model initialize',1,0);
/* Model step function */
void EmbeddedCoderIntro_step(void)
{
  boolean_T rtb_equal_to_count;

  /* RelationalOperator: '<Root>/RelOpt' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/LIMIT'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  rtb_equal_to_count = ((uint8_T)((uint32_T)rtDWork.X + 1U) != 16U);

  /* Outputs for Triggered SubSystem: '<Root>/Amplifier' incorporates:
   *  TriggerPort: '<S1>/Trigger'
   */
  if (rtb_equal_to_count && ((uint32_T)rtPrevZCSigState.Amplifier_Trig_ZCE !=
       POS_ZCSIG)) {
    /* Outport: '<Root>/Output' incorporates:
     *  Gain: '<S1>/Gain'
     *  Inport: '<Root>/Input'
     */
    rtY.Output = rtU.Input << 1U;
  }

  rtPrevZCSigState.Amplifier_Trig_ZCE = rtb_equal_to_count ? (ZCSigState)1 :
    (ZCSigState)0;

  /* End of Outputs for SubSystem: '<Root>/Amplifier' */

  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/RESET'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  if (rtb_equal_to_count) {
    rtDWork.X = (uint8_T)((uint32_T)rtDWork.X + 1U);
  } else {
    rtDWork.X = 0U;
  }

  /* End of Switch: '<Root>/Switch' */
}

Enable Explicit Casting Mode and Generate Code

When you choose Explicit casting mode, the code generator creates explicit data type casts for variables in the generated code.

1. On the Code Generation > Code Style pane, from the Casting modes drop-down list, select Explicit.

set_param('EmbeddedCoderIntro', 'CastingMode', 'Explicit')

2. On the Code Generation pane, click Apply.

3. In the model window, press Ctrl+B to generate code.

slbuild('EmbeddedCoderIntro')
### Starting build procedure for: EmbeddedCoderIntro
### Successful completion of code generation for: EmbeddedCoderIntro

Build Summary

Top model targets built:

Model               Action           Rebuild Reason                   
======================================================================
EmbeddedCoderIntro  Code generated.  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 13.294s

4. In the Code Generation report left pane, click EmbeddedCoderIntro.c to see the code.

file = fullfile('EmbeddedCoderIntro_ert_rtw','EmbeddedCoderIntro.c');
coder.example.extractLines(file,'/* Model step', '/* Model initialize',1,0);
/* Model step function */
void EmbeddedCoderIntro_step(void)
{
  boolean_T rtb_equal_to_count;

  /* RelationalOperator: '<Root>/RelOpt' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/LIMIT'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  rtb_equal_to_count = (boolean_T)((int32_T)(uint8_T)((uint32_T)(int32_T)
    rtDWork.X + 1U) != 16);

  /* Outputs for Triggered SubSystem: '<Root>/Amplifier' incorporates:
   *  TriggerPort: '<S1>/Trigger'
   */
  if (((int32_T)rtb_equal_to_count) && ((int32_T)
       rtPrevZCSigState.Amplifier_Trig_ZCE != (int32_T)POS_ZCSIG)) {
    /* Outport: '<Root>/Output' incorporates:
     *  Gain: '<S1>/Gain'
     *  Inport: '<Root>/Input'
     */
    rtY.Output = rtU.Input << 1;
  }

  rtPrevZCSigState.Amplifier_Trig_ZCE = (ZCSigState)rtb_equal_to_count;

  /* End of Outputs for SubSystem: '<Root>/Amplifier' */

  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/INC'
   *  Constant: '<Root>/RESET'
   *  Sum: '<Root>/Sum'
   *  UnitDelay: '<Root>/X'
   */
  if (rtb_equal_to_count) {
    rtDWork.X = (uint8_T)((uint32_T)(int32_T)rtDWork.X + 1U);
  } else {
    rtDWork.X = (uint8_T)0U;
  }

  /* End of Switch: '<Root>/Switch' */
}

Related Topics