exponenta event banner

Использовать блок вызывающего абонента C с условным выполнением

В этом примере показано, как использовать блок вызывающего абонента C с условным выполнением. Пример модели содержит два блока C Caller, выходы которых являются входными ветвями блока Switch. Каждый блок вызывающего абонента C вызывает одну из пользовательских функций кода C sort_ascend() и sort_descend(). Только одно из значений из входных ветвей передается на выходную сторону блока коммутатора. Функциональный блок C с теми же настройками может также использоваться вместо блока C вызывающего абонента для вызова этих пользовательских функций кода.

Этот пример иллюстрирует следующие концепции:

  • Вызов пользовательского кода C из блока Simulink ® в контексте условного выполнения.

  • Настройка детерминированных функций по функциям в пользовательском коде.

Изучение модели

Эта модель вызывает пользовательский код через блок вызывающего абонента C, который подключен к входной ветви блока коммутатора.

open_system('slexCCallerConditional');
% Create a temporary folder for the build and inspection process.
currentDir=pwd;
[~,cgDir]=rtwdemodir();

Создать код

Пользовательские функции кода в этой модели не были определены как детерминированные функции. Когда код генерируется из модели, обе функции C выполняются во время моделирования и в сгенерированном коде, даже если блок Switch требует вывода только одной из функций.

slbuild(bdroot);
cfile = fullfile(cgDir,'slexCCallerConditional_grt_rtw','slexCCallerConditional.c');
rtwdemodbtype(cfile,'/* Model step', '/* Matfile logging', 1, 0);
### Starting build procedure for: slexCCallerConditional
### Successful completion of build procedure for: slexCCallerConditional

Build Summary

Top model targets built:

Model                   Action                       Rebuild Reason                                    
=======================================================================================================
slexCCallerConditional  Code generated and compiled  Code generation information file does not exist.  

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

/* Model step function */
void slexCCallerConditional_step(void)
{
  real_T rtb_CCallerascend[6];
  real_T rtb_CCallerdescend[6];
  int32_T i;

  /* CCaller: '<Root>/C Caller (ascend)' incorporates:
   *  Inport: '<Root>/In2'
   */
  for (i = 0; i < 6; i++) {
    rtb_CCallerascend[i] = slexCCallerConditional_U.In2[i];
  }

  sort_ascend(rtb_CCallerascend, 6);

  /* End of CCaller: '<Root>/C Caller (ascend)' */

  /* CCaller: '<Root>/C Caller (descend)' incorporates:
   *  Inport: '<Root>/In2'
   */
  for (i = 0; i < 6; i++) {
    rtb_CCallerdescend[i] = slexCCallerConditional_U.In2[i];
  }

  sort_descend(rtb_CCallerdescend, 6);

  /* End of CCaller: '<Root>/C Caller (descend)' */
  for (i = 0; i < 6; i++) {
    /* Switch: '<Root>/Switch' incorporates:
     *  Inport: '<Root>/In1'
     */
    if (slexCCallerConditional_U.In1 > 0.0) {
      /* Outport: '<Root>/Out3' */
      slexCCallerConditional_Y.Out3[i] = rtb_CCallerascend[i];
    } else {
      /* Outport: '<Root>/Out3' */
      slexCCallerConditional_Y.Out3[i] = rtb_CCallerdescend[i];
    }

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

Определение пользовательских детерминированных функций кода

Откройте диалоговое окно «Параметры конфигурации».

На панели Цель моделирования (Simulation Target) в группе Импорт пользовательского кода (Import Custom Code) задайте для функций Determinitic значение By function. Щелкните Указать по функции (Specify by Function) и добавьте функции. sort_ascend и sort_descend в список. Это действие сообщает модели, что указанные пользовательские функции кода имеют детерминированное поведение, то есть одни и те же входные значения функций всегда дают одни и те же выходные данные. Если функция установлена как детерминированная, ее не нужно вызывать, если она находится во входной ветви, соответствующей ложному значению блока Switch.

configset.highlightParameter(bdroot,'DefaultCustomCodeDeterministicFunctions');
set_param(bdroot,'DefaultCustomCodeDeterministicFunctions','ByFunction');
set_param(bdroot,'CustomCodeDeterministicFunctions','sort_ascend,sort_descend');

Создать код снова

Теперь, когда определены детерминированные функции, созданный код является более эффективным, поскольку выполняется только блок C Caller в истинной ветви блока Switch. Такая же эффективность применяется при моделировании модели в Simulink.

slbuild(bdroot);
cfile = fullfile(cgDir,'slexCCallerConditional_grt_rtw','slexCCallerConditional.c');
rtwdemodbtype(cfile,'/* Model step', '/* Matfile logging', 1, 0);
close_system(bdroot, 0);
### Starting build procedure for: slexCCallerConditional
### Successful completion of build procedure for: slexCCallerConditional

Build Summary

Top model targets built:

Model                   Action                       Rebuild Reason                   
======================================================================================
slexCCallerConditional  Code generated and compiled  Generated code was out of date.  

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

/* Model step function */
void slexCCallerConditional_step(void)
{
  real_T rtb_CCallerascend[6];
  int32_T i;

  /* Switch: '<Root>/Switch' incorporates:
   *  Inport: '<Root>/In1'
   */
  if (slexCCallerConditional_U.In1 > 0.0) {
    /* CCaller: '<Root>/C Caller (ascend)' incorporates:
     *  Inport: '<Root>/In2'
     */
    for (i = 0; i < 6; i++) {
      rtb_CCallerascend[i] = slexCCallerConditional_U.In2[i];
    }

    sort_ascend(rtb_CCallerascend, 6);

    /* End of CCaller: '<Root>/C Caller (ascend)' */
  } else {
    /* CCaller: '<Root>/C Caller (descend)' incorporates:
     *  Inport: '<Root>/In2'
     */
    for (i = 0; i < 6; i++) {
      rtb_CCallerascend[i] = slexCCallerConditional_U.In2[i];
    }

    sort_descend(rtb_CCallerascend, 6);

    /* End of CCaller: '<Root>/C Caller (descend)' */
  }

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

  /* Outport: '<Root>/Out3' */
  for (i = 0; i < 6; i++) {
    slexCCallerConditional_Y.Out3[i] = rtb_CCallerascend[i];
  }

  /* End of Outport: '<Root>/Out3' */

См. также

| | |