Как сгенерированный код хранит внутренний сигнал, состояние и данные о параметре

Чтобы вычислить выходные параметры от входных параметров, сгенерированный код хранит некоторый internal data в глобальной памяти. Сигнал, который не соединяется с вводом или выводом корневого уровня (Блок Inport или Outport) является внутренними данными.

Внутренние данные могут также включать:

  • Состояние блока, такое как состояние блока Unit Delay. Алгоритм должен сохранить значение состояния между циклами выполнения, таким образом, сгенерированный код обычно хранит состояния в глобальной памяти (например, как глобальная переменная или поле глобальной переменной структуры).

  • Параметры блоков, такие как параметр Gain блока Gain, значение которого генератор кода не может встроить в коде. Например, генератор кода не может встроить значение нескалярного параметра.

  • Индикатор состояния условно выполняемой подсистемы, такой как активированная подсистема.

Для более эффективного кода можно сконфигурировать оптимизацию, такую как Configuration Parameters> Default parameter behavior и Configuration Parameters> Signal storage reuse, которые пытаются устранить устройство хранения данных для внутренних данных. Однако оптимизация не может устранить устройство хранения данных для некоторых данных, которые используют память в сгенерированном коде.

Когда вы понимаете формат по умолчанию, в котором сгенерированный код хранит внутренние данные, вы можете:

  • Сделайте сигналы доступными и параметры настраиваемый по умолчанию. Можно затем взаимодействовать с и контролировать код во время выполнения.

  • Сгенерируйте эффективный производственный код путем устранения устройства хранения данных для внутренних данных и, в зависимости от оборудования и создайте набор инструментальных средств, управляя размещением в память о данных, которые не может устранить оптимизация.

  • Продвиньте части внутренних данных к интерфейсу модели так, чтобы другие компоненты и системы могли получить доступ к тем данным.

Для получения информации о том, как сгенерированный код обменивается данными со средой вызова через интерфейсы, смотрите, Как Сгенерированный код Обменивается Данными со Средой.

Внутренние данные в сгенерированном коде

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

Исследуйте модель в качестве примера

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

open_system('rtwdemo_roll')

Модель содержит внутренние сигналы, которые не соединяют с корневым уровнем блоки Outport или Inport. Некоторые сигналы имеют имя, такое как сигнал phiCmd.

Модель также содержит некоторые блоки, которые поддерживают данные состояния. Например, в подсистеме BasicRollMode, блок Discrete-Time Integrator маркировал Integrator, поддерживает состояние.

В модели, Параметры конфигурации набора> Генерация кода> Системный конечный файл к grt.tlc.

set_param('rtwdemo_roll','SystemTargetFile','grt.tlc')

Осмотрите установку для упаковки интерфейса Configuration Parameters> Code Generation> Interface> Code. Установка Nonreusable function означает, что сгенерированный код не допускающий повторное использование (повторно используемый).

В данном примере сгенерируйте более простой код путем очистки Параметров конфигурации> Генерация кода> Интерфейс> Усовершенствованные параметры> журналирование MAT-файла.

set_param('rtwdemo_roll','MatFileLogging','off')

Сгенерируйте код одноразового использования

Установите эти параметры конфигурации:

  • Установите поведение параметра По умолчанию на Tunable.

  • Повторное использование устройства хранения данных Четкого сигнала.

set_param('rtwdemo_roll','DefaultParameterBehavior','Tunable',...
    'OptimizeBlockIOStorage','off')

Сгенерируйте код из модели.

rtwbuild('rtwdemo_roll')
### Starting build procedure for model: rtwdemo_roll
### Successful completion of build procedure for model: rtwdemo_roll

rtwdemo_roll.h файла задает несколько типов структуры, которые представляют внутренние данные. Например, структура ввода и вывода блока задает одно поле для каждого внутреннего сигнала в модели. Каждое имя поля выводит с имени блока, который генерирует сигнал или, если вы задаете имя для сигнала с имени сигнала.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,...
    '/* Block signals (default storage) */','} B_rtwdemo_roll_T;',1,1)
/* Block signals (default storage) */
typedef struct {
  real32_T phiCmd;                     /* '<Root>/ModeSwitch' */
  real32_T Abs;                        /* '<S3>/Abs' */
  real32_T FixPtUnitDelay1;            /* '<S7>/FixPt Unit Delay1' */
  real32_T Xnew;                       /* '<S7>/Enable' */
  real32_T TKSwitch;                   /* '<S3>/TKSwitch' */
  real32_T RefSwitch;                  /* '<S3>/RefSwitch' */
  real32_T Integrator;                 /* '<S1>/Integrator' */
  real32_T DispLimit;                  /* '<S1>/DispLimit' */
  real32_T Sum;                        /* '<S1>/Sum' */
  real32_T DispGain;                   /* '<S1>/DispGain' */
  real32_T RateLimit;                  /* '<S1>/RateLimit' */
  real32_T Sum1;                       /* '<S1>/Sum1' */
  real32_T RateGain;                   /* '<S1>/RateGain' */
  real32_T Sum2;                       /* '<S1>/Sum2' */
  real32_T CmdLimit;                   /* '<S1>/CmdLimit' */
  real32_T IntGain;                    /* '<S1>/IntGain' */
  real32_T hdgError;                   /* '<S2>/Sum' */
  real32_T DispGain_a;                 /* '<S2>/DispGain' */
  real32_T Product;                    /* '<S2>/Product' */
  boolean_T NotEngaged;                /* '<S3>/NotEngaged' */
  boolean_T TKThreshold;               /* '<S3>/TKThreshold' */
  boolean_T RefThreshold2;             /* '<S3>/RefThreshold2' */
  boolean_T RefThreshold1;             /* '<S3>/RefThreshold1' */
  boolean_T Or;                        /* '<S3>/Or' */
  boolean_T NotEngaged_e;              /* '<S1>/NotEngaged' */
} B_rtwdemo_roll_T;

Файл задает тип структуры, структуру DWork, чтобы представлять состояния блока, такие как состояние блока Discrete-Time Integrator.

rtwdemodbtype(file,...
    '/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)
/* Block states (default storage) for system '<Root>' */
typedef struct {
  real32_T FixPtUnitDelay1_DSTATE;     /* '<S7>/FixPt Unit Delay1' */
  real32_T Integrator_DSTATE;          /* '<S1>/Integrator' */
  int8_T Integrator_PrevResetState;    /* '<S1>/Integrator' */
} DW_rtwdemo_roll_T;

Файл задает тип структуры, чтобы представлять данные о параметре. Каждые настраиваемые параметры блоков в модели, такой как параметр Усиления блока Gain, появляются как поле этой структуры. Если параметры блоков получают свое значение от переменной MATLAB или объекта Simulink.Parameter, переменная или объект появляются как поле, не параметры блоков.

Файл также задает тип структуры, структуру данных модели реального времени, одно поле которой представляет индикацию во время выполнения относительно того, столкнулся ли сгенерированный код с ошибкой во время выполнения.

rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
    '/* Block parameters (default storage) */',1,0)
/* Real-time Model Data Structure */
struct tag_RTM_rtwdemo_roll_T {
  const char_T *errorStatus;
};

Для типа структуры, который представляет структуру данных модели реального времени, файл, rtwdemo_roll_types.h создает псевдоним что сгенерированный код более позднее использование, чтобы выделить память для структуры.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll_types.h');
rtwdemodbtype(file,'/* Forward declaration for rtModel */',...
    'RT_MODEL_rtwdemo_roll_T;',1,1)
/* Forward declaration for rtModel */
typedef struct tag_RTM_rtwdemo_roll_T RT_MODEL_rtwdemo_roll_T;

Используя эти типы структуры, файл rtwdemo_roll.c задает (выделяет память для), глобальные переменные структуры, которые хранят внутренние данные для сгенерированного алгоритма. Файл также задает переменные, которые представляют структуру данных модели реального времени и указатель на структуру.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    '= &rtwdemo_roll_M_;',1,1)
/* Block signals (default storage) */
B_rtwdemo_roll_T rtwdemo_roll_B;

/* Block states (default storage) */
DW_rtwdemo_roll_T rtwdemo_roll_DW;

/* External inputs (root inport signals with default storage) */
ExtU_rtwdemo_roll_T rtwdemo_roll_U;

/* External outputs (root outports fed by signals with default storage) */
ExtY_rtwdemo_roll_T rtwdemo_roll_Y;

/* Real-time model */
RT_MODEL_rtwdemo_roll_T rtwdemo_roll_M_;
RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M = &rtwdemo_roll_M_;

Функция модели step, которая представляет первичный образцовый алгоритм, использует интерфейс void void (без аргументов).

rtwdemodbtype(file,...
    '/* Model step function */','void rtwdemo_roll_step(void)',1,1)
/* Model step function */
void rtwdemo_roll_step(void)

В функциональном определении алгоритм выполняет вычисления и промежуточные результаты хранилищ в структурах состояния и сигнала путем прямого доступа к глобальным переменным. Алгоритм также считывает данные о параметре из соответствующей глобальной переменной. Например, в подсистеме BasicRollMode, код, сгенерированный для сигнала чтений и записей блока Integrator, состояния и данных о параметре из структур.

rtwdemodbtype(file,'/* DiscreteIntegrator: ''<S1>/Integrator'' *',...
    '/* End of DiscreteIntegrator: ''<S1>/Integrator'' */',1,1)
  /* DiscreteIntegrator: '<S1>/Integrator' */
  if (rtwdemo_roll_B.NotEngaged_e || (rtwdemo_roll_DW.Integrator_PrevResetState
       != 0)) {
    rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;
  }

  if (rtwdemo_roll_DW.Integrator_DSTATE >= rtwdemo_roll_P.intLim) {
    rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.intLim;
  } else {
    if (rtwdemo_roll_DW.Integrator_DSTATE <= rtwdemo_roll_P.Integrator_LowerSat)
    {
      rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_LowerSat;
    }
  }

  rtwdemo_roll_B.Integrator = rtwdemo_roll_DW.Integrator_DSTATE;

Из-за интерфейса void void и прямого доступа к данным, функция не повторно используема. Если вы вызываете функцию многократно в приложении, каждый вызов записывает данные к глобальным переменным структуры, и последующий вызов может считать те данные, приводящие к неумышленной интерференции между вызовами.

Образцовая функция инициализации rtwdemo_roll_initialize инициализирует все внутренние данные, чтобы обнулить. Функция также инициализирует ошибочное состояние путем вызывания специализированной макро-функции. Функция инициализации непосредственно получает доступ к глобальным переменным, что означает, что функция не повторно используема.

rtwdemodbtype(file,'/* Model initialize function */',...
    'sizeof(DW_rtwdemo_roll_T));',1,1)
/* Model initialize function */
void rtwdemo_roll_initialize(void)
{
  /* Registration code */

  /* initialize error status */
  rtmSetErrorStatus(rtwdemo_roll_M, (NULL));

  /* block I/O */
  (void) memset(((void *) &rtwdemo_roll_B), 0,
                sizeof(B_rtwdemo_roll_T));

  /* states (dwork) */
  (void) memset((void *)&rtwdemo_roll_DW, 0,
                sizeof(DW_rtwdemo_roll_T));

Функция затем инициализирует состояния блока в структуре DWork к начальным значениям, которые задают параметры блоков в модели. Два из трех состояний в модели имеют настраиваемые начальные значения, таким образом, код инициализирует их путем чтения данных из структуры параметров.

rtwdemodbtype(file,...
    '/* SystemInitialize for Atomic SubSystem: ''<Root>/RollAngleReference'' */',...
    '/* Model terminate function */',1,0)
  /* SystemInitialize for Atomic SubSystem: '<Root>/RollAngleReference' */
  /* InitializeConditions for UnitDelay: '<S7>/FixPt Unit Delay1' */
  rtwdemo_roll_DW.FixPtUnitDelay1_DSTATE = rtwdemo_roll_P.LatchPhi_vinit;

  /* End of SystemInitialize for SubSystem: '<Root>/RollAngleReference' */

  /* SystemInitialize for Atomic SubSystem: '<Root>/BasicRollMode' */
  /* InitializeConditions for DiscreteIntegrator: '<S1>/Integrator' */
  rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;
  rtwdemo_roll_DW.Integrator_PrevResetState = 0;

  /* End of SystemInitialize for SubSystem: '<Root>/BasicRollMode' */
}

Сгенерируйте повторно используемый код

Можно сконфигурировать сгенерированный код как повторно используемый, что означает, что можно вызвать функции точки входа многократно в приложении. С этой настройкой, вместо того, чтобы непосредственно получить доступ к глобальным переменным, функции точки входа принимают внутренние данные через формальные параметры (аргументы указателя). С этими аргументами указателя каждый вызов может поддержать внутренние данные в наборе отдельных глобальных переменных, предотвратив неумышленное взаимодействие между вызовами.

В модели, упаковке интерфейса Configuration Parameters> Code Generation> Interface> Code набора к Reusable function.

set_param('rtwdemo_roll','CodeInterfacePackaging','Reusable function')

Сгенерируйте код из модели.

rtwbuild('rtwdemo_roll')
### Starting build procedure for model: rtwdemo_roll
### Successful completion of build procedure for model: rtwdemo_roll

Теперь, в rtwdemo_roll.h, структура данных модели реального времени содержит указатели на ошибочную индикацию, внутренние данные, и первичный входной параметр и выходные данные в форме ExtU и подструктур ExtY (поля которого представляют блоки Inport и Outport на корневом уровне модели).

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
    '/* External data declarations for dependent source files */',1,0)
/* Real-time Model Data Structure */
struct tag_RTM_rtwdemo_roll_T {
  const char_T *errorStatus;
  B_rtwdemo_roll_T *blockIO;
  P_rtwdemo_roll_T *defaultParam;
  ExtU_rtwdemo_roll_T *inputs;
  ExtY_rtwdemo_roll_T *outputs;
  boolean_T paramIsMalloced;
  DW_rtwdemo_roll_T *dwork;
};

Чтобы вызвать сгенерированный код многократно в приложении, ваш код должен выделить память для структуры данных модели реального времени на вызов. rtwdemo_roll.c файла задает специализированную функцию, которая выделяет память для новой структуры данных модели реального времени и возвращает указатель на структуру. Функция также выделяет память для подструктур, которые поля в структуре данных модели указывают на, такие как структура DWork.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Model data allocation function */',...
    'RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)',1,1)
/* Model data allocation function */
RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)

Функция модели step принимает аргумент, который представляет структуру данных модели реального времени.

rtwdemodbtype(file,'/* Model step function */','void rtwdemo_roll_step',1,1)
/* Model step function */
void rtwdemo_roll_step(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)

В функциональном определении алгоритм сначала извлекает каждый указатель от структуры данных модели реального времени в локальную переменную.

rtwdemodbtype(file,'*rtwdemo_roll_P_e =','rtwdemo_roll_M->outputs;',1,1)
  P_rtwdemo_roll_T *rtwdemo_roll_P_e = ((P_rtwdemo_roll_T *)
    rtwdemo_roll_M->defaultParam);
  B_rtwdemo_roll_T *rtwdemo_roll_B = ((B_rtwdemo_roll_T *)
    rtwdemo_roll_M->blockIO);
  DW_rtwdemo_roll_T *rtwdemo_roll_DW = ((DW_rtwdemo_roll_T *)
    rtwdemo_roll_M->dwork);
  ExtU_rtwdemo_roll_T *rtwdemo_roll_U = (ExtU_rtwdemo_roll_T *)
    rtwdemo_roll_M->inputs;
  ExtY_rtwdemo_roll_T *rtwdemo_roll_Y = (ExtY_rtwdemo_roll_T *)
    rtwdemo_roll_M->outputs;

Затем чтобы получить доступ к внутренним данным, хранимым в глобальной памяти, алгоритм взаимодействует с этими локальными переменными.

rtwdemodbtype(file,'/* DiscreteIntegrator: ''<S1>/Integrator'' */',...
    '/* End of DiscreteIntegrator: ''<S1>/Integrator'' */',1,1)
  /* DiscreteIntegrator: '<S1>/Integrator' */
  if (rtwdemo_roll_B->NotEngaged_e ||
      (rtwdemo_roll_DW->Integrator_PrevResetState != 0)) {
    rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P_e->Integrator_IC;
  }

  if (rtwdemo_roll_DW->Integrator_DSTATE >= rtwdemo_roll_P_e->intLim) {
    rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P_e->intLim;
  } else {
    if (rtwdemo_roll_DW->Integrator_DSTATE <=
        rtwdemo_roll_P_e->Integrator_LowerSat) {
      rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P_e->Integrator_LowerSat;
    }
  }

  rtwdemo_roll_B->Integrator = rtwdemo_roll_DW->Integrator_DSTATE;

Точно так же образцовая функция инициализации принимает структуру данных модели реального времени как аргумент.

rtwdemodbtype(file,...
    '/* Model initialize function */','void rtwdemo_roll_initialize',1,1)
/* Model initialize function */
void rtwdemo_roll_initialize(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)

Поскольку каждый вызов, который вы выполняете к функции точки входа, взаимодействует с отдельной структурой данных модели реального времени, вы избегаете неумышленного взаимодействия между вызовами.

Устраните внутренние данные с оптимизацией генерации кода

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

set_param('rtwdemo_roll','DefaultParameterBehavior','Inlined',...
    'OptimizeBlockIOStorage','on',...
    'LocalBlockOutputs','on')

В этом примере, для более простого кода, упаковки интерфейса Code набора к Nonreusable function.

set_param('rtwdemo_roll','CodeInterfacePackaging','Nonreusable function')

Сгенерируйте код из модели.

rtwbuild('rtwdemo_roll')
### Starting build procedure for model: rtwdemo_roll
### Successful completion of build procedure for model: rtwdemo_roll

Теперь, rtwdemo_roll.h не задает структуру для вводов и выводов блока. Для всех внутренних сигналов в модели, оптимизация или устраненное устройство хранения данных или созданные переменные локальной функции вместо глобальных полей структуры.

Оптимизация не смогла устранить устройство хранения данных для этих трех состояний блока, таким образом, файл продолжает задавать тип структуры DWork.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,...
    '/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)
/* Block states (default storage) for system '<Root>' */
typedef struct {
  real32_T FixPtUnitDelay1_DSTATE;     /* '<S7>/FixPt Unit Delay1' */
  real32_T Integrator_DSTATE;          /* '<S1>/Integrator' */
  int8_T Integrator_PrevResetState;    /* '<S1>/Integrator' */
} DW_rtwdemo_roll_T;

Код, сгенерированный для блока Discrete-Time Integrator теперь, хранит и выходные данные состояния только в структуре DWork.

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Update for DiscreteIntegrator: ''<S1>/Integrator''',...
    '/* End of Update for DiscreteIntegrator: ''<S1>/Integrator'' */',1,1)
  /* Update for DiscreteIntegrator: '<S1>/Integrator' incorporates:
   *  Gain: '<S1>/IntGain'
   */
  rtwdemo_roll_DW.Integrator_DSTATE += 0.5F * rtb_TKSwitch * 0.025F;
  if (rtwdemo_roll_DW.Integrator_DSTATE >= 5.0F) {
    rtwdemo_roll_DW.Integrator_DSTATE = 5.0F;
  } else {
    if (rtwdemo_roll_DW.Integrator_DSTATE <= -5.0F) {
      rtwdemo_roll_DW.Integrator_DSTATE = -5.0F;
    }
  }

  rtwdemo_roll_DW.Integrator_PrevResetState = (int8_T)rtb_NotEngaged_f;

Оптимизация также устранила устройство хранения данных для параметров блоков в модели. Например, в блоке Discrete-Time Integrator, Верхний предел насыщения и Более низкие предельные параметры насыщения установлены в intLim и -intLim. intLim является объектом Simulink.Parameter, который хранит значение 5. В коде, сгенерированном для Интегратора Дискретного времени, эти параметры блоков и intLim появляются как встроенные литеральные числа 5.0F и -5.0F.

Если модель содержит параметр, который генератор кода не может встроить непосредственно (например, параметр массива), код задает тип структуры, который представляет данные. Эта постоянная структура параметров использует спецификатор типа хранения const, таким образом, некоторые наборы инструментальных средств сборки могут оптимизировать ассемблерный код далее.

Локальные переменные в сгенерированном коде

Когда вы выбираете оптимизацию Configuration Parameters> Enable local block outputs, генератор кода пытается привести к более эффективному коду путем представления внутренних сигналов как локальных переменных вместо полей глобальной структуры. Если память, использованная локальными переменными, рискует превышать стековое пространство, доступное на вашем целевом компьютере, рассмотрите указание на максимальный размер стека установкой Configuration Parameters> Maximum stack size (bytes). Для получения дополнительной информации смотрите размер стека Maximum (байты).

Внешний вид тестовых точек в сгенерированном коде

Тестовая точка является сигналом, который хранится в уникальной ячейке памяти. Для получения информации о включении тестовых точек в вашей модели смотрите Тестовые точки (Simulink).

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

Если у вас есть Embedded Coder®:

Виртуальные шины не появляются в сгенерированном коде, даже когда сопоставлено с тестовой точкой. Чтобы отобразить шину в сгенерированном коде, используйте невиртуальную шину или виртуальную шину, преобразованную в невиртуальную шину блоком Signal Conversion.

Внешний вид переменных рабочей области в сгенерированном коде

Workspace variables является переменными, которые вы используете, чтобы задать значения параметров блоков в модели. Переменные рабочей области включают числовые переменные MATLAB®, и Simulink.Parameter возражает, что вы храните в рабочей области, такой как базовое рабочее пространство, или в словаре данных.

Когда вы устанавливаете Default parameter behavior на Tunable, по умолчанию, переменные рабочей области появляются в сгенерированном коде как настраиваемые поля глобальной структуры параметров. Если вы используете такую переменную, чтобы задать несколько значений параметров блоков, переменная появляется как одно поле глобальной структуры параметров. Код не создает несколько полей, чтобы представлять параметры блоков. Поэтому настройка значения поля во время выполнения кода изменяет математическое поведение модели таким же образом как настройка значения переменной MATLAB или объекта параметра во время симуляции.

Если у вас есть Embedded Coder, можно управлять представлением по умолчанию переменных рабочей области путем определения настроек генерации кода для категорий данных о параметре в Коде, Сопоставляющем Редактор (см., Конфигурируют Генерацию кода По умолчанию для Данных (Embedded Coder)).

  • Категория Local parameters применяется к переменным, которые вы храните в рабочем пространстве модели.

  • Категория Global parameters применяется к переменным, которые вы храните в базовом рабочем пространстве или словаре данных.

Продвиньте внутренние данные интерфейс

По умолчанию генератор кода принимает, что другие системы и компоненты в вашем приложении не должны получать доступ к внутренним данным. Например, внутренние данные подвергаются оптимизации, которая может устранить их из сгенерированного кода. Для прототипирования и тестирования целей, можно получить доступ к внутренним данным путем очистки оптимизации или путем конфигурирования тестовых точек и применения классов памяти (см., Конфигурируют Доступность Данных для Быстрого прототипирования). Для оптимизированного производственного кода сконфигурируйте отдельные элементы данных, чтобы появиться в сгенерированном коде как часть интерфейса модели.

Данные, которые можно продвинуть

В зависимости от повторной входимости сгенерированного кода, то есть, установка, которую вы выбираете для Code interface packaging, можно сконфигурировать каждый элемент данных в модели, чтобы участвовать в интерфейсе путем появления в коде как одна из этих сущностей:

  • Глобальный символ, такой как глобальная переменная или вызов специализированной функции

  • Формальный параметр (аргумент) сгенерированных функций точки входа

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

Категория данныхПоявитесь как глобальный символПоявитесь в качестве аргумента функции точки входа
Блок Root-level Inport or OutportТолько для неповторно используемой модели.Да.
Сигнал, соединяющий два блокаТолько для неповторно используемой модели.

Только для повторно используемой модели и только как поле структуры.

Также соедините сигнал с блоком Outport корневого уровня.

Состояние блокаТолько для неповторно используемой модели.Только для повторно используемой модели и только как поле структуры.
Хранилище данных, такое как Блок памяти Хранилища данныхДа.Только для повторно используемой модели и только как поле структуры.
Параметры блоков или объект параметра, такой как Simulink.ParameterДа.Только как поле структуры.

Алгоритм одно экземпляра

Для алгоритма одно экземпляра (вы устанавливаете Code interface packaging на Nonreusable function), примените классы памяти непосредственно к отдельным элементам данных при помощи Model Data Editor или Property Inspector. С непосредственно прикладным классом памяти элемент данных появляется в коде как глобальный символ, такой как глобальная переменная. Класс памяти также препятствует тому, чтобы оптимизация устранила устройство хранения данных для элемента данных.

Можно применить классы памяти к сигналам, состояниям блока и параметрам блоков. (Для параметров блоков вы применяете классы памяти косвенно через объекты параметра, такие как Simulink.Parameter). Однако для сигнала, рассмотрите соединение сигнала к блоку Outport на корневом уровне модели. Затем опционально, можно применить класс памяти к блоку. В блок-схеме блок Outport показывает, что сигнал представляет систему вывод.

Для получения дополнительной информации о классах памяти, смотрите, Применяют Классы памяти к Отдельному Сигналу, состоянию и Элементам данных Параметра.

Повторно используемый алгоритм

Для повторно используемого алгоритма (вы устанавливаете Code interface packaging на Reusable function), используйте различные методы, чтобы сконфигурировать элементы данных, чтобы появиться в коде как формальные параметры (аргументы) сгенерированных функций точки входа.

Управляйте представлением по умолчанию внутренних данных (Embedded Coder)

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

Управляйте размещением данных в памяти вставкой прагм

Используйте Код, Сопоставляющий Редактор, чтобы задать раздел memory по умолчанию для каждой категории данных, таких как состояния и сигналы (Internal data). В сгенерированном коде ваши пользовательские прагмы или другие художественные оформления окружают определения данных и объявления.

Можно также разделить структуры согласно атомарным подсистемам в модели так, чтобы можно было задать различные разделы памяти по умолчанию для данных стандартных подпрограмм и других алгоритмических субкомпонентов.

Для получения дополнительной информации смотрите Данные об Управлении и Функциональное Размещение в Памяти Вставкой Прагм (Embedded Coder).

Имена элементов управления типов, полей и глобальных переменных для стандартных структур данных

Можно управлять некоторыми характеристиками стандартных структур данных. Для получения дополнительной информации смотрите Характеристики Управления Структур данных (Embedded Coder).

Для дополнительного управления характеристиками структуры, такими как размещение в файлах сгенерированного кода, создают ваш собственный класс структурированного хранилища при помощи Словаря Embedded Coder. Затем примените класс памяти к категориям данных при помощи Кода, Сопоставляющего Редактор. Класс памяти удаляет данные из стандартных структур, создавая другие структуры, которыми можно более точно управлять. Для получения дополнительной информации о применении классов памяти по умолчанию к категориям данных, смотрите, Конфигурируют Генерацию кода По умолчанию для Данных (Embedded Coder). Для получения дополнительной информации о создании класса памяти, смотрите, Задают Классы памяти, Разделы Памяти и Шаблоны функций для Программной архитектуры (Embedded Coder).

Организуйте данные в структуры согласно субкомпонентам

  • В стандартных структурах данных, чтобы создать подструктуры, которые содержат данные для одно экземпляра (неповторно используемая) стандартная подпрограмма или субкомпонент, используют атомарную подсистему, чтобы инкапсулировать соответствующие блоки. В параметрах подсистемы, набор Function packaging к Reusable function. Для получения дополнительной информации смотрите, Генерируют Модульный Функциональный Код для Невиртуальных Подсистем (Embedded Coder).

    Также инкапсулируйте блоки в модели и используйте блок Model. В модели, на которую ссылаются, набор Configuration Parameters> Model Referencing> Total number of instances allowed per top model к Multiple. Для получения дополнительной информации смотрите Генерацию кода Моделей, на которые Ссылаются.

  • Создать отдельные, автономные структуры, которые содержат данные для мультиэкземпляра (повторно используемая) стандартная подпрограмма или субкомпонент, в модели, используют атомарную подсистему, чтобы инкапсулировать соответствующие блоки. В параметрах подсистемы, набор Function packaging к Nonreusable function и выбирают Function with separate data. Для получения дополнительной информации смотрите, Генерируют Модульный Функциональный Код для Невиртуальных Подсистем (Embedded Coder).

    Также инкапсулируйте блоки в модели и используйте блок Model. В модели, на которую ссылаются выберите один из этих методов:

Организуйте данные о сигнале и параметре в значимые, пользовательские структуры и подструктуры

Чтобы организовать произвольные сигналы и параметры в пользовательские структуры и подструктуры, создайте невиртуальные сигналы шины и структуры параметра. Опционально, чтобы препятствовать тому, чтобы оптимизация устранила данные из кода, установите класс памяти сигнала шины или структуры параметра к значению кроме Auto (настройка по умолчанию).

Когда вы добавляете блоки в модель, необходимо явным образом поместить каждый новый сигнал и параметр в шину или структуру.

Для получения дополнительной информации смотрите, Организуют Данные в Структуры в Сгенерированном коде.

Создайте отдельные глобальные переменные вместо полей структуры

Чтобы заставить категорию внутренних данных появиться в сгенерированном коде как отдельные, неструктурированные глобальные переменные вместо полей стандартной структуры данных, примените неструктурированный класс памяти к категории данных при помощи Кода, Сопоставляющего Редактор. Например, примените класс памяти ExportedGlobal. Однако, если вы генерируете мультиэкземпляр, повторно используемый код путем установки параметра конфигурации Code interface packaging на значение кроме Nonreusable function, вы не можете использовать этот метод для некоторых категорий данных (см. Классы памяти Использования в Повторно используемом, Моделях Мультиэкземпляра и Компонентах).

Чтобы применить классы памяти по умолчанию к категориям данных при помощи Кода, Сопоставляющего Редактор, смотрите, Конфигурируют Генерацию кода По умолчанию для Данных (Embedded Coder). Чтобы выбрать класс памяти, смотрите, Выбирают Storage Class for Controlling Data Representation in Generated Code.

Похожие темы