В модели могут существовать два периодических перехода частоты выборки:
Более быстрый блок, приводящий в движение более медленный блок
Более медленный блок, приводящий к более быстрому блоку
В следующих разделах рассматриваются модели с периодическим временем выборки только с нулевым смещением. Другие соображения относятся к многоскоростным моделям, включающим асинхронные задачи. Дополнительные сведения о создании кода для асинхронной многозадачности см. в разделе Асинхронная поддержка.
В многозадачных и псевдозадачных системах разная частота дискретизации может привести к тому, что блоки будут выполняться в неправильном порядке. Чтобы предотвратить возможные ошибки в вычисляемых данных, необходимо управлять выполнением модели при этих переходах. При подключении более быстрых и медленных блоков необходимо добавить между ними блоки Rate Transition или модуль Simulink ®. Быстрые переходы в медленные показаны на следующем рисунке.

На следующем рисунке показаны переходы от медленного к быстрому.

Примечание
Несмотря на то, что блок «Rate Transition» предлагает супернабор возможностей блока «Unit Delay» (для медленно-быстрых переходов) и блока «Zero-Order Hold» (для быстро-медленных переходов), вместо этих блоков следует использовать блок «Rate Transition».
Блоки Rate Transition касаются вопросов целостности данных и детерминированности, связанных с передачей данных между блоками, работающими на разных скоростях.
Целостность данных: проблема целостности данных возникает, когда вход в блок изменяется во время выполнения этого блока. Проблемы целостности данных могут быть вызваны вытеснением.
Рассмотрим следующий сценарий:
Более быстрый блок подает входной сигнал на более медленный блок.
Более медленный блок считывает входное значение, V1 из более быстрого блока, и начинает вычисления, используя это значение.
Вычисления вытесняются другим выполнением более быстрого блока, который вычисляет новое выходное значение V2.
Теперь возникает проблема целостности данных: когда более медленный блок возобновляет выполнение, он продолжает свои вычисления, теперь используя «новое» входное значение V2.
Такая передача данных называется незащищенной. Более быстрый переход к более медленным переходам в реальном времени показывает незащищенную передачу данных.
При защищенной передаче данных выходной V1 более быстрого блока удерживается до тех пор, пока более медленный блок не завершит выполнение.
Детерминированная и недетерминированная передача данных: в детерминированной передаче данных время передачи данных полностью предсказуемо, что определяется частотой дискретизации блоков.
Синхронизация недетерминированной передачи данных зависит от доступности данных, частоты дискретизации блоков и времени, в которое блок приема начинает выполняться относительно блока возбуждения.
Можно использовать блок Rate Transition, чтобы защитить передачу данных в приложении и сделать их детерминированными. Эти характеристики считаются желательными в большинстве применений. Однако блок Rate Transition поддерживает гибкие опции, которые позволяют скомпрометировать целостность данных и детерминизм в пользу более низкой задержки. В следующем разделе приводится краткая информация об этих вариантах.
При обработке передачи данных между задачами генератор кода делает следующие предположения:
Переходы данных происходят между одной задачей чтения и одной задачей записи.
Считывание или запись переменной байтового размера является атомарным.
Когда две задачи взаимодействуют через переход данных, только одна из них может вытеснить другую.
Для периодических задач задача более высокой скорости имеет более высокий приоритет, чем задача более низкой скорости; задача более высокой скорости вытесняет задачу более низкой скорости.
Все задачи выполняются на одном процессоре. Квантирование времени не допускается.
Процессы не запускаются или не перезапускаются (особенно при передаче данных между задачами).
Несколько параметров блока Rate Transition имеют отношение к его использованию в генерации кода для выполнения в реальном времени, как описано ниже. Полное описание блока см. в разделе Переход скорости.
Блок Rate Transition обрабатывает периодические (быстрые-медленные и медленные-быстрые) и асинхронные переходы. При вставке между двумя блоками различных скоростей дискретизации блок Rate Transition автоматически конфигурирует свои входные и выходные скорости дискретизации для типа перехода; нет необходимости указывать, является ли переход медленным к быстрому или быстрому к медленному (с низким к высокому или с высоким к низкому приоритетом для асинхронных задач).
Критическим решением, которое необходимо принять при конфигурировании блока Rate Transition, является выбор механизма передачи данных для использования между двумя скоростями. Выбор зависит от безопасности, использования памяти и производительности. Как показано на следующем рисунке в диалоговом окне параметра блока «Rate Transition», механизм передачи данных управляется двумя опциями.

При выборе этого параметра данные, передаваемые между скоростями, сохраняют свою целостность (передача данных защищена). При сбросе этого параметра данные могут не сохранять свою целостность (передача данных не защищена). По умолчанию выбран параметр Обеспечить целостность данных во время передачи данных.
Обеспечение детерминированной передачи данных (максимальная задержка): этот параметр поддерживается для периодических задач со смещением нулевых и быстрых и медленных скоростей, кратных друг другу. Если выбран этот параметр, блок «Rate Transition» ведет себя как блок «Zero-Order Hold» (для быстрых-медленных переходов) или блок «Unit Delay» (для медленных-быстрых переходов). Блок Rate Transition управляет синхронизацией передачи данных полностью предсказуемым способом. При сбросе этого параметра перенос данных является недетерминированным. По умолчанию для переходов между периодическими скоростями со смещением, равным нулю, выбирается параметр Обеспечить детерминированную передачу данных (максимальная задержка); для асинхронных переходов он не может быть выбран.
Блок Rate Transition предлагает три режима работы в отношении передачи данных. По уровню безопасности:
Защищенный/детерминированный (по умолчанию): это самый безопасный режим. Недостатком этого режима является то, что он вводит детерминированную задержку в систему для случая медленных-быстрых периодических переходов скорости. В этом случае задержка, введенная блоком Rate Transition, является периодом выборки более медленной задачи. В случае быстрых-медленных периодических переходов скорости блок Rate Transition не вводит дополнительную задержку.
Protected/NonDeterministic: В этом режиме для медленных и быстрых периодических переходов скорости целостность данных защищается двойной буферизацией данных, передаваемых между скоростями. Для быстрых-медленных периодических переходов скорости используется флаг семафора. Блоки в нисходящем направлении от блока Rate Transition используют последние доступные данные из блока, который управляет блоком Rate Transition. Максимальная задержка меньше или равна одному периоду выборки более быстрой задачи.
Недостатками этого режима являются его недетерминированные сроки. Преимуществом этого режима является его низкая задержка.
Unprotected/NonDeterministic: этот режим не рекомендуется для критически важных приложений. Задержка этого режима такая же, как для защищенного/недетерминированного режима, но требования к памяти снижены, так как не требуются ни двойная буферизация, ни семафоры. То есть блок Rate Transition ничего не делает в этом режиме, кроме как пропускать сигналы; он просто существует, чтобы уведомить вас, что переход скорости существует (и может вызвать сгенерированный код для вычисления неверных ответов). Однако при выборе этого режима генерируется наименьший объем кода.
Примечание
В незащищенном режиме (выбран параметр «Обеспечить целостность данных во время передачи данных») блок Rate Transition не делает ничего другого, кроме как позволяет переходу скорости существовать в модели.
Время выборки на выходном порте блока перехода скорости может быть дискретным или фиксированным только на второстепенном временном шаге. Это означает, что когда блок Rate Transition наследует непрерывное время выборки из своего целевого блока, он рассматривает наследуемое время выборки как фиксированное во второстепенном шаге времени. Следовательно, выходная функция блока Rate Transition выполняется только на основных временных этапах. Если время выборки блока назначения является непрерывным, время выборки на выходе блока перехода скорости - это время выборки базовой скорости (если решатель является фиксированным шагом) или время выборки с сохранением нулевого порядка (если решатель является переменным шагом).
Механизм Simulink может обнаруживать несовпадающие переходы скорости в многозадачной модели во время схемы обновления и автоматически вставлять блоки Rate Transition для их обработки. Чтобы включить эту функцию, выберите параметр конфигурации модели Automatically handle rate transfer for data transfer. По умолчанию этот параметр снят. При выборе этого параметра:
Simulink обрабатывает переходы между периодическим временем выборки и асинхронными задачами.
Simulink вставляет скрытые блоки Rate Transition в блок-схему.
Генератор кода создает код для блоков Rate Transition, которые были автоматически вставлены. Этот код идентичен коду, сгенерированному для блоков Rate Transition, вставленных вручную.
Автоматически вставленные блоки Rate Transition работают в защищенном режиме для периодических и асинхронных задач. Изменить это поведение нельзя. Для периодических задач автоматически вставленные блоки Rate Transition работают с уровнем детерминизма, заданным параметром конфигурации модели Deterministic data transfer. Значение по умолчанию: Whenever possible, что обеспечивает детерминизм для передачи данных между периодическими временами выборки, которые связаны целочисленным кратным. Дополнительные сведения см. в разделе Детерминированная передача данных. Для использования других режимов необходимо вставить блоки Rate Transition и задать их режимы вручную.
Например, в этой модели SineWave2 имеет время выборки 2, а SineWave3 - 3.

При выборе параметра конфигурации модели Автоматическая обработка перехода скорости для передачи данных Simulink вставляет блок перехода скорости между каждым блоком синусоидальной волны и блоком изделия. Вставленные блоки имеют значения параметров для согласования времени выборки блока синусоидальной волны.
Если скорости дискретизации входного порта и выходного порта в модели не кратны друг другу, Simulink вставляет блок перехода скорости, частота дискретизации которого является наибольшим общим делителем (GCD) из двух скоростей. Если ни один другой блок в модели не содержит этой новой скорости, во время моделирования возникает ошибка. В этом случае необходимо вручную вставить блок Rate Transition.
При выборе параметра конфигурации модели Автоматическая обработка скорости перехода для передачи данных Simulink вставляет блоки скорости перехода в пути с несоответствующими скоростями перехода. По умолчанию эти блоки скрыты. Чтобы визуализировать вставленные блоки, обновите схему. Метки значков появляются в модели и указывают, где Simulink вставлял блоки Rate Transition на этапе компиляции. Например, в этой модели три блока Rate Transition были вставлены между двумя блоками Sine Wave и мультиплексором и интегратором при компиляции модели. Метки значков ZOH и DbBuf указывают на эти блоки.

Можно отображать или скрывать метки значков. Откройте вкладку Отладка (Debug). В разделе Diagnostics галереи Information Overlays/Sample Time выберите или снимите флажок Automatic Rate Transitions.
Чтобы настроить скрытые блоки изменения скорости так, чтобы они были видны, щелкните правой кнопкой мыши метку значка и выберите «Вставить блок изменения скорости».

При отображении скрытых блоков Rate Transition:
Можно просмотреть тип вставленного блока Rate Transition и расположение блока в модели.
Можно задать параметр блока «Начальные условия».
Можно изменить параметры блока для переноса ставок.
Проверьте изменения в модели, обновив схему.

Отображение вставленных блоков Rate Transition несовместимо с моделями export-function.
Дополнительные сведения о типах блоков Rate Transition см. в разделе Rate Transition.
Дополнительные сведения о типах блоков Rate Transition см. в разделе Rate Transition.
В этих разделах описываются случаи, в которых блоки Rate Transition требуются для периодических переходов частоты дискретизации. Диаграммы обсуждения и синхронизации в этих разделах основаны на предположении, что блок Rate Transition используется в его режиме по умолчанию (защищенный/детерминированный). Параметры конфигурации модели Обеспечение целостности данных при передаче данных и Обеспечение детерминированной передачи данных (максимальная задержка). Эти параметры используются для автоматически вставляемых блоков Rate Transition.
В модели, где более быстрый блок приводит в движение более медленный блок, имеющий прямой проход, выходы более быстрого блока вычисляются первыми. В интервалах моделирования, где более медленный блок не выполняется, моделирование продвигается быстрее, потому что есть меньше блоков для выполнения. Следующая диаграмма иллюстрирует эту ситуацию.

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

На приведенном выше рисунке более быстрый блок выполняется второй раз до того, как более медленный блок завершит выполнение. Это может привести к непредсказуемым результатам, поскольку входные данные для медленной задачи изменяются. В этой ситуации данные могут не сохранять целостность.
Чтобы избежать этой ситуации, механизм Simulink должен удерживать выходы 1-секундного (более быстрого) блока до тех пор, пока не завершится выполнение 2-секундного (более медленного) блока. Способ достижения этого заключается в вставке блока «Переход скорости» между блоками «1 секунда» и «2 секунды». Вход в более медленный блок не изменяется во время его выполнения, сохраняя целостность данных.

Предполагается, что блок Rate Transition используется в режиме по умолчанию (защищенный/детерминированный).
Блок Rate Transition выполняется с частотой дискретизации более медленного блока, но с приоритетом более быстрого блока.

При добавлении блока Rate Transition блок выполняется перед 2-м вторым блоком (его приоритет выше), и его выходное значение остается постоянным, в то время как 2-й блок выполняется (выполняется с более низкой частотой дискретизации).
В модели, где более медленный блок приводит в движение более быстрый блок, движок Simulink снова вычисляет выход блока возбуждения первым. Во время интервалов выборки, где выполняется только более быстрый блок, моделирование продвигается быстрее.
На следующем рисунке показана последовательность выполнения.

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

Эта временная диаграмма иллюстрирует две проблемы:
Выполнение более медленного блока разделяется более чем на один интервал более быстрого блока. В этом случае более быстрая задача выполняется второй раз, прежде чем более медленная задача завершит выполнение. Это означает, что входные данные для более быстрой задачи могут иметь неверные значения в течение некоторого времени.
Чем быстрее выполняется блок перед более медленным блоком (который находится в обратном направлении от способа моделирования Simulink). В этом случае 1-секундный блок выполняется первым; но входные данные для более быстрой задачи не были вычислены. Это может привести к непредсказуемым результатам.
Чтобы устранить эти проблемы, необходимо вставить блок Rate Transition между блоками медленнее и быстрее.

Предполагается, что блок Rate Transition используется в режиме по умолчанию (защищенный/детерминированный).
На следующем рисунке показана последовательность синхронизации, которая приводит к добавленному блоку перехода скорости.

Три ключевых момента о переходах на этой схеме (см. номера в окружностях):
Вывод блока Rate Transition выполняется в течение 1 секунды, но с меньшей скоростью (2 секунды). Выходные данные блока «Rate Transition» подают блоки задач на 1 секунду.
Обновление Rate Transition использует выходные данные 2-секундной задачи для обновления ее внутреннего состояния.
Выходные данные Rate Transition в задаче 1 секунды используют состояние Rate Transition, которое было обновлено в задаче 2 секунды.
Первая проблема устраняется, поскольку блок перехода скорости обновляется с более низкой скоростью и с приоритетом более медленного блока. Вход в блок перехода скорости (который является выходом блока замедления) считывается после завершения выполнения блока замедления.
Вторая проблема устраняется, поскольку блок перехода скорости выполняется с более низкой скоростью, и его выходной сигнал не изменяется во время вычисления более быстрого блока, которым он управляет. Выходная часть блока перехода скорости выполняется с частотой дискретизации более медленного блока, но с приоритетом более быстрого блока. Поскольку блок Rate Transition управляет более быстрым блоком и фактически имеет тот же самый приоритет, он выполняется перед более быстрым блоком.
Примечание
Это использование блока Rate Transition изменяет модель. Выход более медленного блока теперь задерживается на один шаг времени по сравнению с выходом без блока перехода скорости.
volatile Ключевое словоПри выборе параметра конфигурации модели Обеспечение целостности данных во время передачи данных код, генерируемый для блока Rate Transition, определяет глобальные буферы и семафоры и использует их для защиты целостности передаваемых данных.
В частности, для многозадачных приложений задачи (скорости), участвующие в передаче данных, могут записываться в передаваемые данные, буферы и семафоры в моменты времени, которые компилятор не может предвидеть. Чтобы предотвратить оптимизацию кода сборки компилятором таким образом, чтобы нарушалась целостность передаваемых данных, генератор кода применяет ключевое слово volatile в буферы и семафоры. Генератор кода не применяется volatile к глобальной переменной, которая представляет перенесенные данные, поскольку volatile буферы и семафоры обычно обеспечивают достаточную защиту.
С помощью Embedded Coder ® можно явно применитьvolatile к передаваемым данным путем применения встроенного пользовательского класса хранения Volatile на вход блока Rate Transition. Например, этот метод можно использовать для защиты целостности данных, совместно используемых внешним кодом с сгенерированным кодом.
Кроме того, для защиты данных, совместно используемых внешним кодом с сгенерированным кодом, можно записать собственные функции C, которые считывают и записывают данные защищенным способом. Затем можно применить пользовательский класс хранения GetSet к данным в модели, что заставляет созданный код вызывать функции вместо непосредственного доступа к данным.
Дополнительные сведения о применении volatile, см. раздел Защита глобальных данных с помощью квалификаторов типа const и volative (Embedded Coder). Для получения дополнительной информации о GetSetсм. раздел Доступ к данным через функции с помощью класса хранения GetSet (встроенный кодер).
Можно указать, является ли генератор кода встроенным кодом и данными, которые он создает для блоков Rate Transition с кодом модели, или помещает код и данные в отдельные функции, вызываемые кодом модели. Управление осуществляется путем выбора параметра блочного кода Rate Transition. Разделение блочного кода Rate Transition и данных с кодом и данными алгоритма позволяет независимо анализировать, оптимизировать и тестировать блочный код и код алгоритма Rate Transition. По умолчанию код блока Rate Transition устанавливается в соответствии с кодом алгоритма и данными. Можно разделить код и данные так, чтобы созданный код содержал отдельные get и set функции, которые model_step вызов функций и выделенная структура для данных состояния. Созданный код также содержит отдельные start и initialize функции, которые model_initialize вызовы функций.
Пример модели
Открыть пример модели rtwdemo_ratetrans. Эта многоскоростная многозадачная модель содержит несколько блоков Rate Transition, работающих в разных режимах.
open_system('rtwdemo_ratetrans'); set_param('rtwdemo_ratetrans','SystemTargetFile','ert.tlc'); set_param('rtwdemo_ratetrans','GenerateComments', 'Off');
Отдельный код для блоков изменения скорости
В диалоговом окне «Параметры конфигурации» для параметра кода блока «Переход скорости» установлено значение Function. Создайте код для модели. Код находится в файлах rtwdemo_ratetrans.c и rtwdemo_ratetrans.h.
currentDir = pwd;
[~,cgDir] = rtwdemodir();
slbuild('rtwdemo_ratetrans');### Starting build procedure for: rtwdemo_ratetrans ### Successful completion of build procedure for: rtwdemo_ratetrans Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================================== rtwdemo_ratetrans 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 16.581s
hfile=fullfile(cgDir, 'rtwdemo_ratetrans_ert_rtw','rtwdemo_ratetrans.h'); rtwdemodbtype(hfile,'typedef struct {','} DW;', 1, 1);
typedef struct {
real_T OutportBufferForOut3[20];
real_T Integrator1_DSTATE[20];
real_T Integrator2_DSTATE[20];
real_T Integrator3_DSTATE[20];
real_T Integrator1_PREV_U[20];
real_T Integrator2_PREV_U[20];
real_T Integrator3_PREV_U[20];
uint32_T Algorithm_PREV_T;
struct {
uint_T Algorithm_RESET_ELAPS_T:1;
} bitsForTID1;
uint8_T Integrator1_SYSTEM_ENABLE;
uint8_T Integrator2_SYSTEM_ENABLE;
uint8_T Integrator3_SYSTEM_ENABLE;
} DW;
Для блоков Rate Transition данные состояния не находятся в глобальной структуре состояний. DW_rtwdemo_ratetrans_T. Эти данные находятся в собственной структуре в файле rtwdemo_ratetrans_rtb.h.
Этот код находится в файле rtwdemo_ratetrans.c.
cfile=fullfile(cgDir, 'rtwdemo_ratetrans_ert_rtw','rtwdemo_ratetrans.c'); rtwdemodbtype(cfile,'void rtwdemo_ratetrans_step0','void rtwdemo_ratetrans_terminate(void)', 1, 0);
void rtwdemo_ratetrans_step0(void)
{
(rtM->Timing.RateInteraction.TID0_1)++;
if ((rtM->Timing.RateInteraction.TID0_1) > 1) {
rtM->Timing.RateInteraction.TID0_1 = 0;
}
rtwdemo_rate_DetAndIntegS2F_get(rtY.Out1);
rtwdemo_ratetr_IntegOnlyS2F_get(rtY.Out2);
memcpy(&rtY.Out3[0], &rtDW.OutportBufferForOut3[0], 20U * sizeof(real_T));
rtwdemo_rate_DetAndIntegF2S_set(rtU.In1);
rtwdemo_ratetr_IntegOnlyF2S_set(rtU.In2);
}
void rtwdemo_ratetrans_step1(void)
{
real_T rtb_DetAndIntegF2S[20];
real_T rtb_IntegOnlyF2S[20];
real_T tmp;
int32_T i;
uint32_T Algorithm_ELAPS_T;
rtwdemo_rate_DetAndIntegF2S_get(rtb_DetAndIntegF2S);
rtwdemo_ratetr_IntegOnlyF2S_get(rtb_IntegOnlyF2S);
if (rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T) {
Algorithm_ELAPS_T = 0U;
} else {
Algorithm_ELAPS_T = rtM->Timing.clockTick1 - rtDW.Algorithm_PREV_T;
}
rtDW.Algorithm_PREV_T = rtM->Timing.clockTick1;
rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T = false;
tmp = 0.001 * (real_T)Algorithm_ELAPS_T;
for (i = 0; i < 20; i++) {
if (rtDW.Integrator1_SYSTEM_ENABLE == 0) {
rtDW.Integrator1_DSTATE[i] += tmp * rtDW.Integrator1_PREV_U[i];
}
if (rtDW.Integrator2_SYSTEM_ENABLE == 0) {
rtDW.Integrator2_DSTATE[i] += tmp * rtDW.Integrator2_PREV_U[i];
}
if (rtDW.Integrator3_SYSTEM_ENABLE == 0) {
rtDW.Integrator3_DSTATE[i] += tmp * rtDW.Integrator3_PREV_U[i];
}
rtDW.OutportBufferForOut3[i] = rtDW.Integrator3_DSTATE[i];
rtDW.Integrator1_PREV_U[i] = rtb_DetAndIntegF2S[i];
rtDW.Integrator2_PREV_U[i] = rtb_IntegOnlyF2S[i];
rtDW.Integrator3_PREV_U[i] = rtU.In3[i];
}
rtDW.Integrator1_SYSTEM_ENABLE = 0U;
rtDW.Integrator2_SYSTEM_ENABLE = 0U;
rtDW.Integrator3_SYSTEM_ENABLE = 0U;
rtwdemo_rate_DetAndIntegS2F_set(rtDW.Integrator1_DSTATE);
rtwdemo_ratetr_IntegOnlyS2F_set(rtDW.Integrator2_DSTATE);
rtM->Timing.clockTick1++;
}
void rtwdemo_ratetrans_initialize(void)
{
rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T = true;
rtDW.Integrator1_SYSTEM_ENABLE = 1U;
rtDW.Integrator2_SYSTEM_ENABLE = 1U;
rtDW.Integrator3_SYSTEM_ENABLE = 1U;
}
rtwdemo_ratetrans_step0 и rtwdemo_ratetrans_step1 функции содержат вызовы get и set функции. Эти функции содержат код блока Rate Transition. Эти определения функций находятся в файле rtwdemo_ratetrans_rtb.c.
Создание встроенного кода для блоков изменения скорости
В диалоговом окне «Параметры конфигурации» задайте для параметра кода блока «Переход скорости» значение Inline. Создайте код для модели. Код находится в файлах rtwdemo_ratetrans.c и rtwdemo_ratetrans.h.
set_param('rtwdemo_ratetrans','RateTransitionBlockCode','Inline'); slbuild('rtwdemo_ratetrans')
### Starting build procedure for: rtwdemo_ratetrans ### Successful completion of build procedure for: rtwdemo_ratetrans Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================= rtwdemo_ratetrans 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 12.189s
Этот код теперь находится в файле rtwdemo_ratetrans.h.
hfile=fullfile(cgDir, 'rtwdemo_ratetrans_ert_rtw','rtwdemo_ratetrans.h'); rtwdemodbtype(hfile, 'typedef struct {', '} DW;', 1, 1);
typedef struct {
real_T Integrator1_DSTATE[20];
real_T Integrator2_DSTATE[20];
real_T Integrator3_DSTATE[20];
real_T DetAndIntegS2F_Buffer0[20];
volatile real_T IntegOnlyS2F_Buffer[40];
real_T DetAndIntegF2S_Buffer[20];
volatile real_T IntegOnlyF2S_Buffer0[20];
real_T Integrator1_PREV_U[20];
real_T Integrator2_PREV_U[20];
real_T Integrator3_PREV_U[20];
uint32_T Algorithm_PREV_T;
struct {
uint_T Algorithm_RESET_ELAPS_T:1;
} bitsForTID1;
volatile int8_T IntegOnlyS2F_ActiveBufIdx;
volatile int8_T IntegOnlyF2S_semaphoreTaken;
uint8_T Integrator1_SYSTEM_ENABLE;
uint8_T Integrator2_SYSTEM_ENABLE;
uint8_T Integrator3_SYSTEM_ENABLE;
} DW;
Для блоков Rate Transition данные состояния не находятся в глобальной структуре состояний. DW_rtwdemo_ratetrans_T. Эти данные находятся в собственной структуре в файле rtwdemo_ratetrans_rtb.h.
Этот код теперь находится в файле rtwdemo_ratetrans_rtb.c.
cfile=fullfile(cgDir, 'rtwdemo_ratetrans_ert_rtw','rtwdemo_ratetrans.c'); rtwdemodbtype(cfile,'void rtwdemo_ratetrans_step0','void rtwdemo_ratetrans_terminate(void)', 1, 0);
void rtwdemo_ratetrans_step0(void)
{
int32_T i;
int32_T i_0;
(rtM->Timing.RateInteraction.TID0_1)++;
if ((rtM->Timing.RateInteraction.TID0_1) > 1) {
rtM->Timing.RateInteraction.TID0_1 = 0;
}
if (rtM->Timing.RateInteraction.TID0_1 == 1) {
memcpy(&rtY.Out1[0], &rtDW.DetAndIntegS2F_Buffer0[0], 20U * sizeof(real_T));
}
i = rtDW.IntegOnlyS2F_ActiveBufIdx * 20;
for (i_0 = 0; i_0 < 20; i_0++) {
rtY.Out2[i_0] = rtDW.IntegOnlyS2F_Buffer[i_0 + i];
}
if (rtM->Timing.RateInteraction.TID0_1 == 1) {
memcpy(&rtDW.DetAndIntegF2S_Buffer[0], &rtU.In1[0], 20U * sizeof(real_T));
}
if (rtDW.IntegOnlyF2S_semaphoreTaken == 0) {
for (i = 0; i < 20; i++) {
rtDW.IntegOnlyF2S_Buffer0[i] = rtU.In2[i];
}
}
}
void rtwdemo_ratetrans_step1(void)
{
real_T rtb_IntegOnlyF2S[20];
real_T tmp;
int32_T i;
uint32_T Algorithm_ELAPS_T;
rtDW.IntegOnlyF2S_semaphoreTaken = 1;
for (i = 0; i < 20; i++) {
rtb_IntegOnlyF2S[i] = rtDW.IntegOnlyF2S_Buffer0[i];
}
rtDW.IntegOnlyF2S_semaphoreTaken = 0;
if (rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T) {
Algorithm_ELAPS_T = 0U;
} else {
Algorithm_ELAPS_T = rtM->Timing.clockTick1 - rtDW.Algorithm_PREV_T;
}
rtDW.Algorithm_PREV_T = rtM->Timing.clockTick1;
rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T = false;
tmp = 0.001 * (real_T)Algorithm_ELAPS_T;
for (i = 0; i < 20; i++) {
if (rtDW.Integrator1_SYSTEM_ENABLE == 0) {
rtDW.Integrator1_DSTATE[i] += tmp * rtDW.Integrator1_PREV_U[i];
}
if (rtDW.Integrator2_SYSTEM_ENABLE == 0) {
rtDW.Integrator2_DSTATE[i] += tmp * rtDW.Integrator2_PREV_U[i];
}
if (rtDW.Integrator3_SYSTEM_ENABLE != 0) {
rtY.Out3[i] = rtDW.Integrator3_DSTATE[i];
} else {
rtY.Out3[i] = tmp * rtDW.Integrator3_PREV_U[i] + rtDW.Integrator3_DSTATE[i];
}
rtDW.Integrator1_PREV_U[i] = rtDW.DetAndIntegF2S_Buffer[i];
rtDW.Integrator2_PREV_U[i] = rtb_IntegOnlyF2S[i];
rtDW.Integrator3_DSTATE[i] = rtY.Out3[i];
rtDW.Integrator3_PREV_U[i] = rtU.In3[i];
rtDW.DetAndIntegS2F_Buffer0[i] = rtDW.Integrator1_DSTATE[i];
}
rtDW.Integrator1_SYSTEM_ENABLE = 0U;
rtDW.Integrator2_SYSTEM_ENABLE = 0U;
rtDW.Integrator3_SYSTEM_ENABLE = 0U;
for (i = 0; i < 20; i++) {
rtDW.IntegOnlyS2F_Buffer[i + (rtDW.IntegOnlyS2F_ActiveBufIdx == 0) * 20] =
rtDW.Integrator2_DSTATE[i];
}
rtDW.IntegOnlyS2F_ActiveBufIdx = (int8_T)(rtDW.IntegOnlyS2F_ActiveBufIdx == 0);
rtM->Timing.clockTick1++;
}
void rtwdemo_ratetrans_initialize(void)
{
rtDW.bitsForTID1.Algorithm_RESET_ELAPS_T = true;
rtDW.Integrator1_SYSTEM_ENABLE = 1U;
rtDW.Integrator2_SYSTEM_ENABLE = 1U;
rtDW.Integrator3_SYSTEM_ENABLE = 1U;
}
Код встроен в функции rtwdemo_ratetrans_step0 и rtwdemo_ratetrans_step1.
Ограничение
Генератор кода не разделяет код и данные для блоков перехода скорости, которые имеют сигналы переменного размера или находятся внутри блока для каждой подсистемы.
См. также
Код блока перехода скорости (встроенный кодер)
bdclose('rtwdemo_ratetrans');
rtwdemoclean;
cd(currentDir)