Можно задать поведение S-функций шаг расчета mdlInitializeSampleTimes
. Ваша S-функция может наследовать свои скорости от блоков, которые управляют ею или определяют свои собственные скорости.
Можно задать скорости S-функций (т.е. шаги расчета) как
Основанные на блоках шаги расчета
Основанные на порте шаги расчета
Гибридные блоковые и портовые шаги расчета
С основанными на блоках шагами расчета, S-функция задает набор рабочих скоростей для блока в целом во время фазы инициализации симуляции. С шагами расчета на основе портов S-функция задает шаг расчета для каждого входного и выходного порта индивидуально во время инициализации. Во время фазы симуляции, с основанными на блоках шагами расчета, S-функция обрабатывает все входы и выходы каждый раз, когда попадание выборки происходит для блока. В отличие от этого, с шагами расчета на основе портов блок обрабатывает конкретный порт только, когда для этого порта происходит попадание выборки.
Для примера рассмотрим две скорости дискретизации, 0,5 и 0,25 секунды, соответственно:
В блочном методе выбор 0,5 и 0,25 предписывает блоку выполнять входы и выходы с шагом 0,25 секунды.
В методе, основанном на порте, установка входного порта 0,5 и выходного порта 0,25 заставляет блок обрабатывать входы на 2 Гц и выходы на 4 Гц.
Вы должны использовать основанные на портах шаги расчета, если ваше приложение требует неравных частот дискретизации для входа и выхода или если вы не хотите, чтобы накладные расходы были связаны с запущенными входными и выходными портами с самой высокой частотой дискретизации вашего блока.
В некоторых приложениях блоку S-Function может потребоваться работать внутри с одной или несколькими скоростями дискретизации во время ввода или вывода сигналов с другими скоростями. Гибридный метод определения частот дискретизации на основе блоков и портов позволяет создавать такие блоки.
В типичных приложениях вы задаете только один основанный на блоках шаг расчета. Расширенные S-функции могут потребовать спецификации шагов расчета на основе портов или нескольких блоков.
S-функции MEX на C задают основанную на блоках информацию о шаге расчета в
В следующих двух разделах обсуждается, как задать основанные на блоках шаги расчета для S-функций C MEX. В третьем разделе представлен простой пример, который показывает, как задать шаги расчета в mdlInitializeSampleTimes
. Подробный пример см. в разделе mixedm.c
.
Чтобы сконфигурировать свою S-функцию для основанных на блоках шагов расчета, используйте
ssSetNumSampleTimes
(S,numSampleTimes);
где numSampleTimes > 0
. Это говорит Simulink® движком, который ваша S-функция имеет основанные на блоках шаги расчета. механизм вызывает mdlInitializeSampleTimes
, который, в свою очередь, устанавливает шаги расчета.
mdlInitializeSampleTimes
задает две части информации о выполнении:
Время дискретизации и смещения - В mdlInitializeSampleTimes
, вы должны задать период выборки и смещение для каждого шага расчета используя ssSetSampleTime
и ssSetOffsetTime
. Если применимо, можно вычислить соответствующий период выборки и смещение до установки их, например, путем вычисления наилучшего шага расчета для блока на основе параметров диалога S-функции, полученных с помощью ssGetSFcnParam
.
Вызовы функций - В mdlInitializeSampleTimes
, использование ssSetCallSystemOutput
для определения элементов выхода, которые выполняют вызовы функций. См. sfun_fcncall.c
для примера и реализации Подсистем вызова функций с S-функциями для объяснения этой S-функции.
Вы задаете шаги расчета как пары [
sample_time, offset_time
]
, с использованием этих макросов
ssSetSampleTime
(S, sampleTimePairIndex, sample_time)ssSetOffsetTime
(S, offsetTimePairIndex, offset_time)
где sampleTimePairIndex
и offsetTimePairIndex
начинается с 0.
Допустимыми парами шага расчета являются (заглавные значения являются макросами, определенными в simstruc.h
):
[CONTINUOUS_SAMPLE_TIME, 0.0 ] [CONTINUOUS_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET] [discrete_sample_period, offset ] [VARIABLE_SAMPLE_TIME , 0.0 ]
Кроме того, можно задать, что шаг расчета наследуется от ведущего блока, в этом случае S-функция может иметь только одну пару шага расчета,
[INHERITED_SAMPLE_TIME, 0.0 ]
или
[INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET]
Примечание
Если ваша S-функция наследует свои шаги расчета, необходимо указать, безопасно ли использовать S-функцию в модели-ссылке, т.е. модели, на которую ссылается другая модель. Дополнительные сведения см. Модель-ссылку разделе «Определение наследования Шага расчета».
Следующие инструкции могут помочь в определении шагов расчета:
Непрерывная функция, которая изменяется во время незначительных шагов интегрирования, должна регистрировать [CONTINUOUS_SAMPLE_TIME, 0.0]
Шаг расчета.
Непрерывная функция, которая не меняется во время незначительных шагов интегрирования, должна регистрировать [CONTINUOUS_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET]
Шаг расчета.
Дискретная функция, которая изменяется с заданной скоростью, должна регистрировать дискретную пару шага расчета
[discrete_sample_period, offset]
где
discrete_sample_period > 0.0
и
0.0 <= offset < discrete_sample_period
Дискретная функция, которая изменяется с переменной скоростью, должна регистрировать дискретную [VARIABLE_SAMPLE_TIME, 0.0]
с переменным шагом Шаг расчета. В S-функциях MEX на C,
mdlGetTimeOfNextVarHit
вызывается функция, чтобы получить время следующей выборки хита для дискретной задачи с переменным шагом. The VARIABLE_SAMPLE_TIME
может использоваться только с решателями переменного шага.
Если ваша функция не имеет внутреннего шага расчета, вы должны указать, что она наследуется в соответствии со следующими рекомендациями:
Функция, которая изменяется по мере изменения входных параметров, даже во время незначительных шагов интегрирования, должна регистрировать [INHERITED_SAMPLE_TIME, 0.0]
Шаг расчета.
Функция, которая изменяется по мере изменения входов, но не изменяется во время незначительных шагов интегрирования (что означает, удерживается во время мелких шагов), должна регистрировать [INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET]
Шаг расчета.
Для проверки на наличие выборки удара во время выполнения (в mdlOutputs
или mdlUpdate
), использовать ssIsSampleHit
или ssIsContinuousTask
макрос. Для примера используйте следующий фрагмент кода для проверки на непрерывную выборку попадание:
if (ssIsContinuousTask
(S,tid)) {
}
Чтобы определить, имеет ли третье (дискретное) задание попадание, используйте следующий фрагмент кода:
if (ssIsSampleHit
(S,2,tid) {
}
Механизм Simulink всегда присваивает индекс 0
к непрерывной частоте дискретизации, если она существует, однако вы получаете неправильные результаты, если используете ssIsSampleHit(S,0,tid)
.
Этот пример задает, что существует два дискретных шага расчета с периодами 0,01 и 0,5 секунды.
static void mdlInitializeSampleTimes
(SimStruct *S)
{
ssSetSampleTime(S, 0, 0.01);
ssSetOffsetTime(S, 0, 0.0);
ssSetSampleTime(S, 1, 0.5);
ssSetOffsetTime(S, 1, 0.0);
} /* End of mdlInitializeSampleTimes. */
Вы не можете использовать основанные на портах шаги расчета с S-функциями, которые не имеют ни входных, ни выходных портов. Если S-функция использует основанные на портах шаги расчета и не имеет портов, S-функция производит ошибки, когда модель Simulink обновляется или запускается. Если количество входа или выхода портов в S-функции переменно, в S-функцию должна быть добавлена дополнительная защита, чтобы убедиться, что общее количество портов не достигает нуля.
Чтобы использовать основанные на портах шаги расчета в вашей функции C MEX S, необходимо указать количество шагов расчета как основанных на портах в функции S mdlInitializeSizes
метод:
ssSetNumSampleTimes
(S, PORT_BASED_SAMPLE_TIMES)
Вы также должны задать шаг расчета каждого входного и выходного порта в S-функции mdlInitializeSizes
метод, с использованием следующих макросов
ssSetInputPortSampleTime
(S, idx, period)ssSetInputPortOffsetTime
(S, idx, offset)ssSetOutputPortSampleTime
(S, idx, period)ssSetOutputPortOffsetTime
(S, idx, offset)
Вызов ssSetNumSampleTimes
могут быть помещены до или после того, как основанные на порте шаги расчета фактически указаны в mdlInitializeSizes
. Однако, если ssSetNumSampleTimes
не конфигурирует S-функцию для использования основанных на портах шагов расчета, любые шаги расчета, установленные на портах, будут проигнорированы.
Для любого данного порта можно задать
Конкретный шаг расчета и периода
Для примера следующий код устанавливает шаг расчета порта первого входа S-функции 0.1
и время смещения в 0
.
ssSetInputPortSampleTime(S, 0, 0.1); ssSetInputPortOffsetTime(S, 0, 0);
Унаследованные шаги расчета (-1
), т.е. порт наследует свой шаг расчета от порта, к которому он подключен (см. «Определение унаследованных Шагов расчета для порта»)
Постоянный шаг расчета (Inf
), т.е. сигнал, поступающий от порта, является постоянным (см. «Установка постоянного шага расчета (Inf) для порта»)
Примечание
Чтобы быть пригодными для использования в триггируемой подсистеме, все ваши порты S-функции должны быть унаследованы (–1
) или постоянный шаг расчета (Inf
). Для получения дополнительной информации см. «Настройка портовых Шагов расчета для использования в Триггируемые подсистемы».
Чтобы указать, что шаг расчета порта наследуется в S-функции MEX на C, mdlInitializeSizes
метод должен установить его период равным -1
и его смещение на 0
. Для примера следующий код задает унаследованные шаги расчета для первого порта входа функции MEX S на C:
ssSetInputPortSampleTime(S, 0, -1); ssSetInputPortOffsetTime(S, 0, 0);
Когда вы задаете основанные на портах шаги расчета, механизм Simulink вызывает mdlSetInputPortSampleTime
и mdlSetOutputPortSampleTime
для определения скоростей наследуемых сигналов.
После того, как все тарифы определены, механизм вызывает mdlInitializeSampleTimes
. Несмотря на то, что на данной точке нет необходимости инициализировать шаги расчета на основе портов, механизм вызывает этот метод, чтобы предоставить вашей S-функции возможность сконфигурировать соединения вызова функции. Таким образом, ваша S-функция должна обеспечить реализацию для этого метода независимо от того, использует ли он основанные на порте шаги расчета или соединения вызова функции. Несмотря на то, что вы можете предоставить пустую реализацию, вы можете использовать ее, чтобы проверить уместность шагов расчета, которые унаследовал блок во время распространения выборки. Использовать
и ssGetInputPortSampleTime
в ssGetOutputPortSampleTime
mdlInitializeSampleTimes
для получения значений унаследованных шагов расчета. Например, следующий код в mdlInitializeSampleTimes
проверяет, унаследовал ли первый вход S-функции непрерывный шаг расчета.
if (!ssGetInputPortSampleTime(S,0)) { ssSetErrorStatus(S,"Cannot inherit a continuous sample time.") };
Примечание
Если вы задаете, что ваши порты S-функции наследуют свой шаг расчета, вы также должны указать, безопасно ли использовать S-функцию в ссылочной модели, то есть модели, на которую ссылается другая модель. Дополнительные сведения см. Модель-ссылку разделе «Определение наследования Шага расчета».
Если вы записываете TLC код, чтобы сгенерировать inlined код из S-функции, и если TLC код содержит Outputs
функция, вы должны изменить код TLC, если эти условия верны:
Порт выхода имеет постоянное значение. Он использует или наследует шаг расчета Inf
.
S-функция является многократной S-функцией или использует основанные на порте шаги расчета.
В этом случае код TLC должен сгенерировать код для порта выхода с постоянными значениями при помощи функции OutputsForTID
вместо функции Outputs
. Для получения дополнительной информации смотрите Задание Постоянного Шага Расчета (Inf) для Порта.
Чтобы предотвратить наследование портами шага расчета Inf
, установите опцию SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME
в коде S-функции. В этом случае можно использовать функцию TLC Outputs
для генерации кода для выходных портов с постоянными значениями.
Inf
) для портаЕсли ваша S-функция использует основанные на портах шаги расчета, она может задать время расчета Inf
на любом из его портов. Основанный на порте шаг расчета Inf
означает, что сигнал, входящий или выходящий из порта, остается постоянным.
Чтобы сделать порт выходным постоянным значением, S-функция должна:
Использование ssSetOptions
в своей mdlInitializeSizes
метод, чтобы добавить поддержку для шага расчета Inf
:
ssSetOptions(S,SS_OPTION_ALLOW_CONSTANT_PORT_SAMPLE_TIME);
Примечание
Эта опция заставляет порты S-функции поддерживать шаг расчета Inf
, включая порты, которые наследуют их шаги расчета от других блоков. Если какие-либо порты S-функции, которые наследуют шаг расчета, не могут иметь шаг расчета Inf
, возникает ошибка. Установите шаги расчета для этих портов, используя mdlSetInputPortSampleTime
и mdlSetOutputPortSampleTime
методы.
Установите значение шага расчета порта равным Inf
и его смещение на 0
, например,
ssSetInputPortSampleTime(S,0,mxGetInf()); ssSetInputPortOffsetTime(S,0,0);
Сдать на хранение mdlOutputs
является ли метод tid
аргумент равен CONSTANT_TID
и если да, задайте значение выхода порта, если он является выходом портом.
Чтобы увидеть пример того, как создать порты, которые выводят постоянное значение, смотрите sfun_port_constant.c
, исходный файл для sfcndemo_port_constant
пример.
Если вы записываете TLC код, чтобы сгенерировать inlined код из S-функции, и если TLC код содержит Outputs
function, измените код TLC, если все эти условия верны:
Порт выхода имеет постоянное значение. Он использует или наследует шаг расчета Inf
.
S-функция является многократной S-функцией или использует основанные на порте шаги расчета.
В этом случае код TLC должен сгенерировать код для порта выхода с постоянными значениями при помощи функции OutputsForTID
вместо функции Outputs
. Функция OutputsForTID
генерирует выходной код для постоянного компонента S-функции. Если вы конфигурируете модель, чтобы сгенерировать многозадачный код, OutputsForTID
также генерирует выходной код для периодических компонентов S-функции.
Для примера просмотрите файл TLC sfun_port_constant.tlc
для функции C S sfun_port_constant.c
в sfcndemo_port_constant модели
. В модели вход блочного S-Function2 имеет постоянное значение на протяжении всей симуляции. В коде S-функции первый выходной порт наследует шаг расчета входного порта, поэтому выходной порт также имеет постоянное значение. Код S-функции непосредственно задает постоянное значение для второго выходного порта.
В коде TLC, если порт имеет постоянное значение, функция Outputs
не генерирует код для первого выходного порта. Функция не генерирует код для второго выходного порта ни при каких обстоятельствах, потому что порт всегда имеет постоянное значение.
Для этой S-функции OutputsForTID
генерирует код для выходных портов, которые имеют постоянное значение. Генератор кода вызывает функцию OutputsForTID
, и устанавливает аргумент tid
идентификатору задачи, который соответствует постоянным значениям. Только если идентификатор задачи выходного порта соответствует постоянным значениям, это так OutputsForTID
затем сгенерируйте код для порта.
Чтобы использовать S-функцию C MEX в триггируемую подсистему, ваш шаг расчета S-функция на основе портов должна выполнить следующие задачи.
Использование ssSetOptions
в mdlInitializeSizes
метод для указания, что S-функция может выполняться в триггируемую подсистему:
ssSetOptions(S, SS_OPTION_ALLOW_PORT_SAMPLE_TIME_IN_TRIGSS);
Установите все его порты унаследованными (-1
) или постоянный шаг расчета (Inf
) в его mdlInitializeSizes
способ.
Указатель шага расчета в mdlSetInputPortSampleTime
и mdlSetOutputPortSampleTime
методы следующим образом.
Поскольку порты S-функции наследуют свои шаги расчета, механизм Simulink вызывает либо mdlSetInputPortSampleTime
или mdlSetOutputPortSampleTime
во время распространения шага расчета. Макрос ssSampleAndOffsetAreTriggered
может использоваться в этих методах, чтобы определить, находится ли S-функция в триггируемой подсистеме. Если S-функция находится в триггируемой подсистеме, любой метод, который вызывается, должен задать шаг расчета и смещение порта, для которого она вызывается INHERITED_SAMPLE_TIME
(-1
).
Установка шага расчета порта и смещение обоих значений INHERITED_SAMPLE_TIME
указывает, что шаг расчета порта срабатывает, т.е. выдает выход или принимает вход только тогда, когда инициируется подсистема, в которой он находится. Затем метод должен также задать шаги расчета и смещения всех других входных и выходных портов S-функции, чтобы иметь либо активированный, либо постоянный шаг расчета (Inf
), в зависимости от того, что подходит, например,
static void mdlSetInputPortSampleTime(SimStruct *S, int_T portIdx, real_T sampleTime real_T offsetTime) { /* If the S-function resides in a triggered subsystem, the sample time and offset passed to this method are both equal to INHERITED_SAMPLE_TIME. Therefore, if triggered, the following lines set the sample time and offset of the input port to INHERITED_SAMPLE_TIME.*/ ssSetInputPortSampleTime(S, portIdx, sampleTime); ssSetInputPortOffsetTime(S, portIdx, offsetTime); /* If triggered, set the output port to inherited, as well */ if (ssSampleAndOffsetAreTriggered(sampleTime,offsetTime)) { ssSetOutputPortSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOutputPortOffsetTime(S, 0, INHERITED_SAMPLE_TIME); /* Note, if there are additional input and output ports on this S-function, they should be set to either inherited or constant at this point, as well. */ } }
Нет способа, чтобы S-функция, проживающая в триггируемой подсистеме, предсказала, вызовет ли механизм Simulink mdlSetInputPortSampleTime
или mdlSetOutputPortSampleTime
чтобы задать шаги расчета порта. По этой причине оба метода должны иметь возможность правильно задать шаги расчета всех портов, поэтому механизм должен вызывать только один из методов в одно время.
В mdlUpdate
и mdlOutputs
, использование ssGetPortBasedSampleTimeBlockIsTriggered
чтобы проверить, находится ли S-функция в триггируемой подсистеме, и если да, используйте соответствующие алгоритмы для вычисления ее состояний и выходов.
См. sfun_port_triggered.c
, исходный файл для sfcndemo_port_triggered
пример модели, для примера того, как создать S-функцию, которая может использоваться в триггируемой подсистеме.
Гибридный метод назначения шагов расчета комбинирует основанные на блоках и основанные на портах методы. Вы сначала задаете, в mdlInitializeSizes
, общее количество скоростей, с которыми работает ваш блок, включая как блочные, так и входные и выходные скорости, используя ssSetNumSampleTimes
.
Затем установите SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED
опция, использование ssSetOptions
, чтобы сообщить механизму симуляции, что вы собираетесь использовать основанный на порте метод, чтобы задать скорости входного и выходного портов индивидуально. Далее, как и в основанном на блоках методе, вы задаете периоды и смещения всех частот блока, как внутренних, так и внешних, используя
ssSetSampleTime ssSetOffsetTime
Наконец, как и в методе на основе портов, вы задаете скорости для каждого порта, используя
ssSetInputPortSampleTime(S, idx, period) ssSetInputPortOffsetTime(S, idx, offset) ssSetOutputPortSampleTime(S, idx, period) ssSetOutputPortOffsetTime(S, idx, offset)
Обратите внимание, что каждая из назначенных частот портов должна быть такой же, как и одна из ранее объявленных частот блоков. Для примера S-функции см mixedm.c
.
Примечание
Если вы используете SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED
опция, ваша S-функция не может наследовать шаги расчета. Вместо этого необходимо задать скорость, с которой запускается каждый входной и выходной порт.
В многократном блоке S-Function можно инкапсулировать код, который определяет каждое поведение в mdlOutputs
и mdlUpdate
функции с оператором, который определяет, произошла ли выборка столкновение. В S-функции MEX на C ssIsSampleHit
макрос определяет, является ли текущее время выборки хитом в течение заданного шага расчета. Макрос имеет следующий синтаксис:
ssIsSampleHit(S, st_index, tid)
где S
является SimStruct
, st_index
определяет определенный индекс шага расчета и tid
- идентификатор задачи (tid
является аргументом в mdlOutputs
и mdlUpdate
функций).
Например, эти операторы в S-функции C MEX задают три шагов расчета: один для непрерывного поведения и два для дискретного поведения.
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); ssSetSampleTime(S, 1, 0.75); ssSetSampleTime(S, 2, 1.0);
В mdlUpdate
функция, следующий оператор инкапсулирует код, который определяет поведение для шага расчета 0,75 секунды.
if (ssIsSampleHit(S, 1, tid)) { }
Второй аргумент, 1
, соответствует второй шаг расчета, 0,75 секунды.
Используйте следующие линии, чтобы инкапсулировать код, который определяет поведение для непрерывного попадания выборки:
if (ssIsContinuousTask
(S,tid)) {
}
Этот пример задает шаг расчета для блока, который является непрерывным.
/* Initialize the sample time and offset. */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); }
Вы должны добавить этот оператор к mdlInitializeSizes
функция.
ssSetNumSampleTimes(S, 1);
Этот пример задает шаги расчета для гибридного блока S-Function.
/* Initialize the sample time and offset. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Continuous state sample time and offset. */ ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); /* Discrete state sample time and offset. */ ssSetSampleTime(S, 1, 0.1); ssSetOffsetTime(S, 1, 0.025); }
Во втором шаге расчета смещение заставляет механизм Simulink вызывать mdlUpdate
функция в эти моменты времени: 0,025 секунды, 0,125 секунды, 0,225 секунды и так далее, с шагами 0,1 секунды.
Следующий оператор, который указывает, сколько шагов расчета задано, также появляется в mdlInitializeSizes
функция.
ssSetNumSampleTimes(S, 2);
Для решателей с фиксированным шагом Simulink использует целочисленную арифметику, а не арифметику с плавающей точкой, чтобы вычислить количество попаданий шаг расчета. Следовательно, время задачи является целым числом множителей из их соответствующих периодов шага расчета.
Этот метод вычисления становится важным, если вы рассматриваете выполнение логики Boolean на основе времени задачи в многократных S-функциях. Например, рассмотрим S-функцию, которая имеет два шага расчета. То, что (ssIsSampleHit (S, idx1) == истинный && ssIsSampleHit (S, idx2) == верный, не гарантирует что ssGetTaskTime (S, idx1) == ssGetTaskTime (S, idx2).
Если задачи, выполняемые с различными скоростями, должны совместно использовать данные, необходимо убедиться, что данные, сгенерированные одной задачей, действительны при доступе к другой задаче, выполняемой с другой скоростью. Можно использовать ssIsSpecialSampleHit
макрос в mdlUpdate
или mdlOutputs
стандартная программа многоразовой S-функции, чтобы убедиться, что разделяемые данные действительны. Этот макрос возвращает true
если попадание выборки произошло с одной скоростью, и попадание выборки также произошло с другой скоростью на том же временном шаге. Таким образом, это позволяет более высокоскоростной задаче предоставлять данные, необходимые для более медленной задачи со скоростью, которую может принять более медленная задача. При использовании ssIsSpecialSampleHit
макрос, более медленный шаг расчета должно быть целым числом, кратным более быстрому шагу расчета.
Предположим, для примера, что ваша модель имеет вход порт, работающий с одной скоростью (с индексом шага расчета 0) и выход порт, работающий с более низкой скоростью (с шагом расчета индексом 1). Кроме того, предположим, что вы хотите, чтобы выходной порт выводил значение на текущий момент на вход. Следующий пример иллюстрирует использование этого макроса.
if (ssIsSampleHit(S, 0, tid) { if (ssIsSpecialSampleHit(S, 0, 1, tid) { /* Transfer input to output memory. */ ... } } if (ssIsSampleHit(S, 1, tid) { /* Emit output. */ ... }
В этом примере первый блок запускается, когда попадание выборки происходит со скоростью входа. Если попадание также происходит со скоростью выхода, блок передает вход в выходную память. Второй блок запускается, когда попадание выборки происходит со скоростью выхода. Он передает вывод в своей области памяти на выход блока.
Обратите внимание, что более высокоскоростные задачи всегда выполняются перед более медленными задачами. Таким образом, вход задача в предыдущем примере всегда запускается перед выходом задачей, гарантируя, что действительные данные всегда присутствуют в выходе порту.
Если ваша C MEX S-функция наследует свои шаги расчета от блоков, которые управляют ею, ваша S-функция должна указать, могут ли модели-ссылки, содержащие вашу S-функцию, наследовать шаги расчета от их родительской модели. Если выход S-функции не зависит от его унаследованного шага расчета, используйте ssSetModelReferenceSampleTimeInheritanceRule
макрос, чтобы задать для S-функции шага расчета правила наследования значение USE_DEFAULT_FOR_DISCRETE_INHERITANCE
. В противном случае установите правило на DISALLOW_SAMPLE_TIME_INHERITANCE
запретить наследование шаг расчета для ссылочных моделей, которые включают S-функции, выходы которых зависят от их унаследованного шага расчета и тем самым избегают непреднамеренных ошибок симуляции.
Примечание
Если ваша S-функция не устанавливает этот флаг, механизм Simulink принимает, что он не препятствует модели-ссылке, содержащей его, наследовать время расчета. Однако механизм опционально предупреждает вас, что ссылочная модель содержит S-функции, которые не задают правило наследования шаг расчета (см. «Блоки, выходы которых зависят от наследованного шага расчета»).
Если вы не уверены, зависит ли выход существующей S-функции от ее унаследованного шага расчета, проверьте, вызывает ли она любой из следующих макросов C:
ssGetSampleTime
ssGetInputPortSampleTime
ssGetOutputPortSampleTime
ssGetInputPortOffsetTime
ssGetOutputPortOffsetTime
ssGetInputPortSampleTimeIndex
ssGetOutputPortSampleTimeIndex
или функции TLC:
LibBlockSampleTime
CompiledModel.SampleTime
LibBlockInputSignalSampleTime
LibBlockInputSignalOffsetTime
LibBlockOutputSignalSampleTime
LibBlockOutputSignalOffsetTime
Если ваша S-функция не вызывает ни один из этих макросов или функций, ее выход не зависит от ее унаследованных шагов расчета и, следовательно, безопасно использовать в ссылочных моделях, которые наследуют их шаг расчета.
В качестве примера S-функции, которая препятствует наследованию модели-ссылки своего шага расчета, рассмотрим S-функцию, которая имеет следующее mdlOutputs
метод:
static void mdlOutputs(SimStruct *S, int_T tid) { const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); real_T *y = ssGetOutputPortSignal(S,0); y[0] = ssGetSampleTime(S,tid) * u[0]; }
Выход этой S-функции является ее наследуемым шагом расчета, следовательно, ее выход зависит от ее наследуемого шага расчета, и, следовательно, она небезопасна для использования в ссылке модели. По этой причине эта S-функция должна задать свое правило наследования модели-ссылки следующим образом:
ssSetModelReferenceSampleTimeInheritanceRule (S, DISALLOW_SAMPLE_TIME_INHERITANCE);
ssGetSampleTime
| ssSetInputPortSampleTime
| ssSetSampleTime