Аннотируйте код для выравнивания по ширине проверок Polyspace

В этом примере показано, как включить комментарии в сгенерированном коде, которые подавляют выявление ошибок через Polyspace.

Проверки Polyspace

С программным обеспечением Polyspace Code Prover можно применить верификацию Polyspace к сгенерированному коду Embedded Coder. Программное обеспечение обнаруживает ошибки времени выполнения в сгенерированном коде и помогает вам определить местоположение и зафиксировать отказы модели. Polyspace может подсветить переполнение для определенных операций, которые законны из-за способа, которым генератор кода реализует эти операции. Это законное переполнение не должно быть отмечено Polyspace. Сгенерируйте комментарии в коде, которые подавляют это выявление ошибок.

Генерация кода

1. Откройте модель Simulink в качестве примера mSatAddSub.

model='mSatAddSub';
open_system(model);

2. В приложении Embedded Coder на диалоговом окне Configuration Parameters выключите аннотации Оператора.

set_param('mSatAddSub','OperatorAnnotations','off');

3. Чтобы создать модель и сгенерировать код, нажмите Ctrl+B.

evalc('rtwbuild(''mSatAddSub'')');
%The generated code is:
file = fullfile('mSatAddSub_ert_rtw','mSatAddSub.c');
rtwdemodbtype(file,'/* Model step function */',...
    'End of Sum',1,1);
/* Model step function */
void mSatAddSub_step(void)
{
  uint32_T qY;

  /* Sum: '<Root>/SubUnsigned' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   */
  qY = U1 - U2;
  if (qY > U1) {
    qY = 0U;
  }

  /* Sum: '<Root>/SubUnsigned' */
  USub = qY;

  /* Outport: '<Root>/Out3' */
  mSatAddSub_Y.Out3 = USub;

  /* Matfile logging */
  rt_UpdateTXYLogVars(mSatAddSub_M->rtwLogInfo, (&mSatAddSub_M->Timing.taskTime0));

  /* signal main to stop simulation */
  {                                    /* Sample time: [1.0s, 0.0s] */
    if ((rtmGetTFinal(mSatAddSub_M)!=-1) &&
        !((rtmGetTFinal(mSatAddSub_M)-mSatAddSub_M->Timing.taskTime0) >
          mSatAddSub_M->Timing.taskTime0 * (DBL_EPSILON))) {
      rtmSetErrorStatus(mSatAddSub_M, "Simulation finished");
    }
  }

  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   */
  mSatAddSub_M->Timing.taskTime0 =
    ((time_T)(++mSatAddSub_M->Timing.clockTick0)) *
    mSatAddSub_M->Timing.stepSize0;
}

/* Model initialize function */
void mSatAddSub_initialize(void)
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)mSatAddSub_M, 0,
                sizeof(RT_MODEL_mSatAddSub));
  rtmSetTFinal(mSatAddSub_M, 1.0);
  mSatAddSub_M->Timing.stepSize0 = 1.0;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    rt_DataLoggingInfo.loggingInterval = NULL;
    mSatAddSub_M->rtwLogInfo = &rt_DataLoggingInfo;
  }

  /* Setup for data logging */
  {
    rtliSetLogXSignalInfo(mSatAddSub_M->rtwLogInfo, (NULL));
    rtliSetLogXSignalPtrs(mSatAddSub_M->rtwLogInfo, (NULL));
    rtliSetLogT(mSatAddSub_M->rtwLogInfo, "tout");
    rtliSetLogX(mSatAddSub_M->rtwLogInfo, "");
    rtliSetLogXFinal(mSatAddSub_M->rtwLogInfo, "");
    rtliSetLogVarNameModifier(mSatAddSub_M->rtwLogInfo, "rt_");
    rtliSetLogFormat(mSatAddSub_M->rtwLogInfo, 1);
    rtliSetLogMaxRows(mSatAddSub_M->rtwLogInfo, 1000);
    rtliSetLogDecimation(mSatAddSub_M->rtwLogInfo, 1);

    /*
     * Set pointers to the data and signal info for each output
     */
    {
      static void * rt_LoggedOutputSignalPtrs[] = {
        &mSatAddSub_Y.Out3
      };

      rtliSetLogYSignalPtrs(mSatAddSub_M->rtwLogInfo, ((LogSignalPtrsType)
        rt_LoggedOutputSignalPtrs));
    }

    {
      static int_T rt_LoggedOutputWidths[] = {
        1
      };

      static int_T rt_LoggedOutputNumDimensions[] = {
        1
      };

      static int_T rt_LoggedOutputDimensions[] = {
        1
      };

      static boolean_T rt_LoggedOutputIsVarDims[] = {
        0
      };

      static void* rt_LoggedCurrentSignalDimensions[] = {
        (NULL)
      };

      static int_T rt_LoggedCurrentSignalDimensionsSize[] = {
        4
      };

      static BuiltInDTypeId rt_LoggedOutputDataTypeIds[] = {
        SS_UINT32
      };

      static int_T rt_LoggedOutputComplexSignals[] = {
        0
      };

      static RTWPreprocessingFcnPtr rt_LoggingPreprocessingFcnPtrs[] = {
        (NULL)
      };

      static const char_T *rt_LoggedOutputLabels[] = {
        "USub" };

      static const char_T *rt_LoggedOutputBlockNames[] = {
        "mSatAddSub/Out3" };

      static RTWLogDataTypeConvert rt_RTWLogDataTypeConvert[] = {
        { 0, SS_UINT32, SS_UINT32, 0, 0, 0, 1.0, 0, 0.0 }
      };

      static RTWLogSignalInfo rt_LoggedOutputSignalInfo[] = {
        {
          1,
          rt_LoggedOutputWidths,
          rt_LoggedOutputNumDimensions,
          rt_LoggedOutputDimensions,
          rt_LoggedOutputIsVarDims,
          rt_LoggedCurrentSignalDimensions,
          rt_LoggedCurrentSignalDimensionsSize,
          rt_LoggedOutputDataTypeIds,
          rt_LoggedOutputComplexSignals,
          (NULL),
          rt_LoggingPreprocessingFcnPtrs,

          { rt_LoggedOutputLabels },
          (NULL),
          (NULL),
          (NULL),

          { rt_LoggedOutputBlockNames },

          { (NULL) },
          (NULL),
          rt_RTWLogDataTypeConvert
        }
      };

      rtliSetLogYSignalInfo(mSatAddSub_M->rtwLogInfo, rt_LoggedOutputSignalInfo);

      /* set currSigDims field */
      rt_LoggedCurrentSignalDimensions[0] = &rt_LoggedOutputWidths[0];
    }

    rtliSetLogY(mSatAddSub_M->rtwLogInfo, "yout");
  }

  /* block I/O */

  /* exported global signals */
  USub = 0U;

  /* external inputs */
  U1 = 0U;
  U2 = 0U;

  /* external outputs */
  mSatAddSub_Y.Out3 = 0U;

  /* Matfile logging */
  rt_StartDataLoggingWithStartTime(mSatAddSub_M->rtwLogInfo, 0.0, rtmGetTFinal
    (mSatAddSub_M), mSatAddSub_M->Timing.stepSize0, (&rtmGetErrorStatus
    (mSatAddSub_M)));
}

/* Model terminate function */
void mSatAddSub_terminate(void)
{
  /* (no terminate code required) */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */

4. Осуществите проверку Polyspace. Генератор кода распознает, что самый большой встроенный тип данных является 32-битным. Не возможно насыщать все результаты вычитаний с помощью 0U и больший целочисленный тип данных однословный. Вместо этого программное обеспечение обнаруживает переполнение результатов и направление переполнения, и насыщает результат. Операция отмечается Polyspace, потому что этому не удается распознать насыщение.

5. В приложении Embedded Coder на диалоговом окне Configuration Parameters выключите аннотации Оператора.

set_param('mSatAddSub','OperatorAnnotations',"on");
evalc('rtwbuild(''mSatAddSub'')');

6. Сгенерированный код:

file = fullfile('mSatAddSub_ert_rtw','mSatAddSub.c');
rtwdemodbtype(file,'/* Model step function */',...
    'End of Sum',1,1);
/* Model step function */
void mSatAddSub_step(void)
{
  uint32_T qY;

  /* Sum: '<Root>/SubUnsigned' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   */
  qY = U1 - /*MW:OvSatOk*/ U2;
  if (qY > U1) {
    qY = 0U;
  }

  /* Sum: '<Root>/SubUnsigned' */
  USub = qY;

  /* Outport: '<Root>/Out3' */
  mSatAddSub_Y.Out3 = USub;

  /* Matfile logging */
  rt_UpdateTXYLogVars(mSatAddSub_M->rtwLogInfo, (&mSatAddSub_M->Timing.taskTime0));

  /* signal main to stop simulation */
  {                                    /* Sample time: [1.0s, 0.0s] */
    if ((rtmGetTFinal(mSatAddSub_M)!=-1) &&
        !((rtmGetTFinal(mSatAddSub_M)-mSatAddSub_M->Timing.taskTime0) >
          mSatAddSub_M->Timing.taskTime0 * (DBL_EPSILON))) {
      rtmSetErrorStatus(mSatAddSub_M, "Simulation finished");
    }
  }

  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   */
  mSatAddSub_M->Timing.taskTime0 =
    ((time_T)(++mSatAddSub_M->Timing.clockTick0)) *
    mSatAddSub_M->Timing.stepSize0;
}

/* Model initialize function */
void mSatAddSub_initialize(void)
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)mSatAddSub_M, 0,
                sizeof(RT_MODEL_mSatAddSub));
  rtmSetTFinal(mSatAddSub_M, 1.0);
  mSatAddSub_M->Timing.stepSize0 = 1.0;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    rt_DataLoggingInfo.loggingInterval = NULL;
    mSatAddSub_M->rtwLogInfo = &rt_DataLoggingInfo;
  }

  /* Setup for data logging */
  {
    rtliSetLogXSignalInfo(mSatAddSub_M->rtwLogInfo, (NULL));
    rtliSetLogXSignalPtrs(mSatAddSub_M->rtwLogInfo, (NULL));
    rtliSetLogT(mSatAddSub_M->rtwLogInfo, "tout");
    rtliSetLogX(mSatAddSub_M->rtwLogInfo, "");
    rtliSetLogXFinal(mSatAddSub_M->rtwLogInfo, "");
    rtliSetLogVarNameModifier(mSatAddSub_M->rtwLogInfo, "rt_");
    rtliSetLogFormat(mSatAddSub_M->rtwLogInfo, 1);
    rtliSetLogMaxRows(mSatAddSub_M->rtwLogInfo, 1000);
    rtliSetLogDecimation(mSatAddSub_M->rtwLogInfo, 1);

    /*
     * Set pointers to the data and signal info for each output
     */
    {
      static void * rt_LoggedOutputSignalPtrs[] = {
        &mSatAddSub_Y.Out3
      };

      rtliSetLogYSignalPtrs(mSatAddSub_M->rtwLogInfo, ((LogSignalPtrsType)
        rt_LoggedOutputSignalPtrs));
    }

    {
      static int_T rt_LoggedOutputWidths[] = {
        1
      };

      static int_T rt_LoggedOutputNumDimensions[] = {
        1
      };

      static int_T rt_LoggedOutputDimensions[] = {
        1
      };

      static boolean_T rt_LoggedOutputIsVarDims[] = {
        0
      };

      static void* rt_LoggedCurrentSignalDimensions[] = {
        (NULL)
      };

      static int_T rt_LoggedCurrentSignalDimensionsSize[] = {
        4
      };

      static BuiltInDTypeId rt_LoggedOutputDataTypeIds[] = {
        SS_UINT32
      };

      static int_T rt_LoggedOutputComplexSignals[] = {
        0
      };

      static RTWPreprocessingFcnPtr rt_LoggingPreprocessingFcnPtrs[] = {
        (NULL)
      };

      static const char_T *rt_LoggedOutputLabels[] = {
        "USub" };

      static const char_T *rt_LoggedOutputBlockNames[] = {
        "mSatAddSub/Out3" };

      static RTWLogDataTypeConvert rt_RTWLogDataTypeConvert[] = {
        { 0, SS_UINT32, SS_UINT32, 0, 0, 0, 1.0, 0, 0.0 }
      };

      static RTWLogSignalInfo rt_LoggedOutputSignalInfo[] = {
        {
          1,
          rt_LoggedOutputWidths,
          rt_LoggedOutputNumDimensions,
          rt_LoggedOutputDimensions,
          rt_LoggedOutputIsVarDims,
          rt_LoggedCurrentSignalDimensions,
          rt_LoggedCurrentSignalDimensionsSize,
          rt_LoggedOutputDataTypeIds,
          rt_LoggedOutputComplexSignals,
          (NULL),
          rt_LoggingPreprocessingFcnPtrs,

          { rt_LoggedOutputLabels },
          (NULL),
          (NULL),
          (NULL),

          { rt_LoggedOutputBlockNames },

          { (NULL) },
          (NULL),
          rt_RTWLogDataTypeConvert
        }
      };

      rtliSetLogYSignalInfo(mSatAddSub_M->rtwLogInfo, rt_LoggedOutputSignalInfo);

      /* set currSigDims field */
      rt_LoggedCurrentSignalDimensions[0] = &rt_LoggedOutputWidths[0];
    }

    rtliSetLogY(mSatAddSub_M->rtwLogInfo, "yout");
  }

  /* block I/O */

  /* exported global signals */
  USub = 0U;

  /* external inputs */
  U1 = 0U;
  U2 = 0U;

  /* external outputs */
  mSatAddSub_Y.Out3 = 0U;

  /* Matfile logging */
  rt_StartDataLoggingWithStartTime(mSatAddSub_M->rtwLogInfo, 0.0, rtmGetTFinal
    (mSatAddSub_M), mSatAddSub_M->Timing.stepSize0, (&rtmGetErrorStatus
    (mSatAddSub_M)));
}

/* Model terminate function */
void mSatAddSub_terminate(void)
{
  /* (no terminate code required) */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */

Генератор кода вставляет /*MW:OvSatOk*/ прокомментируйте, что это подавляет ошибку, обнаруженную Polyspace.

7. Закройте модель.

bdclose(model)
rtwdemoclean;

Похожие темы