Инициализация сигнала, состояния и данных о параметре в сгенерированном коде

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

Понимая, как сгенерированный код инициализирует данные, можно:

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

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

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

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

Статическая инициализация и динамическая инициализация

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

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

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

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

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

Инициализация Земли в реальном мире, требующая ненулевого битового шаблона

Каждый элемент данных имеет реальную ground value. Это значение может зависеть от типа данных элемента. Для примера сигнала, тип данных которого double или int8, наземное значение реального мира равняется нулю. Для перечисления значение заземления является представителем перечисления по умолчанию.

Для некоторых видов данных, чтобы представлять значение земли в реальном мире, компьютер сохраняет нуль в памяти (все биты нуль). Однако для некоторых других данных компьютер сохраняет ненулевое значение в памяти. Эти данные включают, например:

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

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

Инициализация сигнала и данных о состоянии

В модели можно управлять начальными значениями сигнала и состояния через параметры блоков. Для примера, чтобы задать начальное значение блока Unit Delay, вы используете параметр Initial condition. В некоторых случаях можно также использовать InitialValue свойство Simulink.Signal объект. Для большинства из этих параметров блоков значение по умолчанию 0.

Можно также инициализировать состояния при помощи блоков State Writer в Initialize Function подсистемах и параметра конфигурации Initial states модели.

По умолчанию сгенерированный код динамически инициализирует сигнал и данные о состоянии (и другие данные, такие как состояние ошибки модели) в сгенерированной функции инициализации. Функция с именем model_initialize по умолчанию выполняет операции инициализации сигнала и состояния в следующем порядке:

  1. Инициализирует сигнал и данные о состоянии в структурах, сгенерированных по умолчанию, таких как структура DWork, к сохраненному значению нуля.

  2. Инициализирует дополнительный сигнал и данные о состоянии, которые не находятся в структурах, сгенерированных по умолчанию, до соответствующего значения земли в реальном мире.

    Эта инициализация применяется только к данным, которые соответствуют обоим из следующих критериев:

    • Сгенерированный код определяет (выделяет память для) данные.

    • Данные используют класс памяти кроме Auto (класс хранения по умолчанию) или Model default (когда Редактор соответствия кода задает Default класс памяти, настройка по умолчанию).

    Например, код применяет эту операцию к элементам данных, которые используют класс памяти ExportedGlobal.

  3. Инициализирует каждый сигнал и состояние к значению реального мира, которое задает модель, например, через параметр Initial condition блока Unit Delay.

  4. Инициализирует каждое состояние к значению реального мира, которое вы присвоите с помощью блока State Writer. Функция выполняет эту инициализацию только, если вы используете Initialize Function подсистему в модели.

  5. Инициализирует каждое состояние до значения реального мира, которое вы задаете с параметр конфигурации <reservedrangesplaceholder0>.

После того, как эта функция инициализации выполняется, каждый элемент данных имеет последнее значение реального мира, которое назначена функции. Например, если вы используете State Writer блок, чтобы инициализировать состояние блока, чтобы 5 при этом также используя параметр конфигурации Initial states, чтобы инициализировать то же состояние в 10, состояние в конечном счете использует 10 как начальное значение.

memset для массовой инициализации

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

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

Настраиваемые начальные значения

Можно сконфигурировать способ, которым настраиваемые параметры блоков, такие как параметр Gain блока Gain, появляются в сгенерированном коде. Большинство параметров блоков, которые устанавливают начальные значения (для примера, Initial condition), настраиваются. Например, параметр конфигурации <reservedrangesplaceholder0> могут определить, появляются ли начальные значения в сгенерированном коде как встроенные константы или как настраиваемые глобальные данные. Можно также использовать объекты параметров и классы памяти для управления представлением этих начальных значений.

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

Чтобы сделать начальные значения настраиваемыми в сгенерированном коде, смотрите Сигнал управления и Инициализация состояния в Сгенерированном коде.

Инициализация параметрических данных

Сгенерированный код статически инициализирует данные параметра до значений, которые вы задаете в Simulink.

Чтобы выразить начальное значение настраиваемого параметра (глобальной переменной) как математическое выражение с включением системных констант или других макросов, что требует Embedded Coder®, см. Инициализация математическим выражением (Embedded Coder).

Виды Параметр данных

Эти элементы модели появляются в сгенерированном коде как данные параметра:

  • Настраиваемые параметры блоков, такие как параметр Gain блока Gain, когда вы задаете Default parameter behavior Tunable. Каждый параметр появляется как поле выделенной глобальной структуры.

  • Некоторые настраиваемые параметры блоков, когда вы задаете Default parameter behavior Inlined. Когда генератор кода не может вписать значение параметра в виде буквального числа, параметр появляется как поле выделенного глобального const структура.

  • Simulink.Parameter объекты, к которым применяется класс памяти, имеющий экспортированные возможности данных. Например, встроенный класс памяти ExportedGlobal имеет экспортированные возможности данных, но класс памяти ImportedExtern не делает.

Инициализация математическим выражением (Embedded Coder)

Можно задать значение объекта параметра (такого как Simulink.Parameter) к математическому выражению с участием чисел, MATLAB® переменные и другие объекты параметров. См. «Задать значение переменных при помощи математического выражения».

Если вы используете этот метод с Embedded Coder, можно сгенерировать код, который инициализирует соответствующие данные параметра (глобальная переменная) с помощью заданного выражения. Для получения примера смотрите Initialize Значения параметров From System Constant или Other Macro (Embedded Coder). Для получения общей информации, включая ограничения, смотрите Генерацию кода объектов параметра со значениями выражения.

Инициализация данных в сгенерированном коде

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

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

Откройте модель примера, rtwdemo_rtwintro.

open_system('rtwdemo_rtwintro')

В галерее Apps нажмите Simulink Coder.

Откройте Model Data Editor. На вкладке Моделирование (Modeling) щелкните Редактор данных модели (Model Data Editor).

Смотрите вкладку Состояния. Для состояния блока Unit Delay начальное значение устанавливается на 0, по умолчанию, что означает, что начальное значение состояния равняется нулю. Состояние называется X.

Установите Начальное Значение ненулевое число, например 5.

set_param('rtwdemo_rtwintro/X','InitialCondition','5')

Откройте редактор Отображения. На вкладке C Code выберите Code Interface > Individual Element Code Mappings.

На вкладке Signals/States в разделе States установите Класс памяти для X на ExportedGlobal. С этой настройкой состояние блока появляется в сгенерированном коде как отдельная глобальная переменная.

coder.mapping.utils.create('rtwdemo_rtwintro');
cm = coder.mapping.api.get('rtwdemo_rtwintro');
setState(cm,'rtwdemo_rtwintro/X','StorageClass','ExportedGlobal');

В модели откройте Amplifier подсистема, которая является триггируемой подсистемой.

В Model Data Editor смотрите вкладку Параметры. Чтобы задать и просмотреть начальные значения сигналов и состояний, можно использовать вкладку Параметры вместо вкладки Состояния.

Этот Model Data Editor показывает, что для блока Outport, выход Initial (InitialOutput) параметру задано значение 0, значение по умолчанию. Этот выход подсистемы требует начального значения, потому что подсистема выполняется условно. Оставьте начальное значение по умолчанию.

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

set_param('rtwdemo_rtwintro','OptimizeBlockIOStorage','off')

В модели смотрите поведение параметра параметра конфигурации Параметров конфигурации > Оптимизация > По умолчанию. Параметру конфигурации задано значение Inlined, что означает, параметры блоков, включая начальные значения, появляются в сгенерированном коде как встроенные литералы или как const данные.

Перейдите к корневому уровню модели.

В Model Data Editor нажмите кнопку Показать/обновить дополнительную информацию.

Возле поля Filter contents нажмите кнопку Filter using selection.

В модели щелкните на маркированном блоке Constant INC. Этот Model Data Editor показывает, что Постоянное значение (Value) параметр блока установлен в INC. INC - переменный MATLAB в базовом рабочем пространстве.

Для INC, установите значение в столбце Значение равным Simulink.Parameter(uint8(1)). MATLAB преобразует INC в Simulink.Parameter объект.

В редакторе Отображения на вкладке Parameters примените класс памяти ExportedGlobal на INC. С помощью этой настройки сгенерированный код определяет INC как глобальная переменная. Что касается инициализации, INC является элементом данных о параметрах.

INC = Simulink.Parameter(INC);
INC.StorageClass = 'ExportedGlobal';

Сгенерируйте и смотрите код

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

slbuild('rtwdemo_rtwintro');
### Starting build procedure for: rtwdemo_rtwintro
### Successful completion of build procedure for: rtwdemo_rtwintro

Build Summary

Top model targets built:

Model             Action                       Rebuild Reason                                    
=================================================================================================
rtwdemo_rtwintro  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 18.384s

В сгенерированном файле rtwdemo_rtwintro.c, вне определения функции, код статически инициализирует данные параметра INC. Значение INC является 1.

file = fullfile('rtwdemo_rtwintro_grt_rtw','rtwdemo_rtwintro.c');
rtwdemodbtype(file,'/* Exported block parameters */','uint8_T INC = 1U;',1,1)
/* Exported block parameters */
uint8_T INC = 1U;                      /* Variable: INC

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

rtwdemodbtype(file,'/* block I/O */','sizeof(B_rtwdemo_rtwintro_T));',1,1)
  /* block I/O */
  (void) memset(((void *) &rtwdemo_rtwintro_B), 0,
                sizeof(B_rtwdemo_rtwintro_T));

Затем функция инициализирует состояние Unit Delay, X, к значению земли. В этом случае значение заземления равняется нулю.

rtwdemodbtype(file,'/* exported global states */','X = 0U;',1,1)
  /* exported global states */
  X = 0U;

Функция также инициализирует другие данные, включая входы и выходы корневого уровня (блоки Inport и Outport), к наземным значениям.

rtwdemodbtype(file,'/* external inputs */','Amplifier_Trig_ZCE = POS_ZCSIG;',1,1)
  /* external inputs */
  rtwdemo_rtwintro_U.Input = 0;

  /* external outputs */
  rtwdemo_rtwintro_Y.Output = 0;
  rtwdemo_rtwintro_PrevZCX.Amplifier_Trig_ZCE = POS_ZCSIG;

Затем функция инициализирует X к значению, заданному в условие Initial параметров блоков.

rtwdemodbtype(file,'/* InitializeConditions for UnitDelay: ''<Root>/X'' */',...
    'X = 5U;',1,1)
  /* InitializeConditions for UnitDelay: '<Root>/X' */
  X = 5U;

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

rtwdemodbtype(file,'SystemInitialize for Triggered SubSystem',...
    'End of SystemInitialize for SubSystem',1,1)
  /* SystemInitialize for Triggered SubSystem: '<Root>/Amplifier' */
  /* SystemInitialize for Outport: '<Root>/Output' incorporates:
   *  Outport: '<S1>/Out'
   */
  rtwdemo_rtwintro_Y.Output = 0;

Смотрите различие между сохраненным значением и реальной ценностью

Для некоторых данных, даже если реальное начальное значение равно нулю, компьютер сохраняет ненулевое значение в памяти. Чтобы наблюдать это различие, примените тип данных с фиксированной точкой смещения к состоянию блока X. Чтобы запустить этот пример, вы должны иметь Fixed-Point Designer™.

В Model Data Editor смотрите вкладку Signals.

В модели кликните выходной сигнал блока Switch, switch_out.

Используйте столбец Data Type Model Data Editor, чтобы задать тип данных сигнала fixdt(1,16,1,3). Это выражение представляет тип данных с фиксированной точкой с наклоном 1 и смещение 3.

set_param('rtwdemo_rtwintro/Switch','OutDataTypeStr',...
    'fixdt(1,16,1,3)')

В модели выберите блок Sum. В Property Inspector, в разделе Signal Attributes, очистите Требовать, чтобы все входы имели совпадающий тип данных.

set_param('rtwdemo_rtwintro/Sum','InputSameDT','off')

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

set_param('rtwdemo_rtwintro','GenCodeOnly','on')

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

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

Build Summary

Top model targets built:

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

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

Функция инициализации модели сначала инициализирует X к реальному основному значению, 0. Из-за типа данных смещения по наклону, который имеет смещение 3, это значение реального мира соответствует сохраненному значению -3.

rtwdemodbtype(file,'/* exported global states */','X = -3;',1,1)
  /* exported global states */
  X = -3;

Затем функция инициализирует X к действительному начальному значению, заданному вами в условие Initial параметров блоков, 5. Это значение реального мира соответствует сохраненному значению 2.

rtwdemodbtype(file,'/* InitializeConditions for UnitDelay: ''<Root>/X'' */',...
    'X = 2;',1,1)
  /* InitializeConditions for UnitDelay: '<Root>/X' */
  X = 2;

Цели моделирования

ЦельДополнительная информация
Явно моделируйте поведение инициализации при помощи блоков

Можно явным образом смоделировать инициализацию и сбросить поведение при помощи Initialize Function и Reset Function подсистем. В подсистемах используйте State Writer блоки, чтобы вычислить и присвоить начальное значение для состояния динамически. Соответствующий код появляется в функции инициализации модели.

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

Предотвратите генерацию кода, который явно инициализирует данные в нуль

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

  • Данные, для которых вы задаете ненулевое начальное значение при помощи параметров блоков.

  • Данные, чье начальное значение в реальном мире является нулем, но чье соответствующее сохраненное значение не является нулем.

  • Перечисленные данные, представитель по умолчанию преобразуется в ненулевое целое число.

Для оптимизации требуется Embedded Coder. Для получения дополнительной информации см. раздел «Удаление кода инициализации нуля».

Сгенерируйте код, который импортирует данные из вашего внешнего кода

Можно сгенерировать код, который повторно использует (импортирует) данные, которые задает ваш внешний код. Для примера можно применить класс памяти ImportedExtern в сигнальную линию, состояние блока или объект параметра. Для импортированных данных:

  • Сгенерированный код не инициализирует данные параметра. Ваш код должен инициализировать импортированные данные параметра.

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

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

См. также

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте