Чтобы создать и сконфигурировать входные порты, метод mdlInitializeSizes
должен сначала задать количество портов S-входного-параметра-функции, с помощью ssSetNumInputPorts
. Затем для каждого входного порта метод должен задать
Размерности входного порта (см. Размерности Входного порта Инициализации),
Если вы хотите, чтобы ваша S-функция наследовала свою размерность от порта, до которого она соединяется, необходимо указать, что порт динамически измерен в mdlInitializeSizes
(см. Калибровку Входного порта Динамически).
Позволяет ли входной порт скалярное расширение входных параметров (см. Скалярное Расширение Вводов),
Имеет ли входной порт прямое сквозное соединение, с помощью ssSetInputPortDirectFeedThrough
Порт имеет прямое сквозное соединение, если входной параметр используется или в mdlOutputs
или в функциях mdlGetTimeOfNextVarHit
. Прямой флаг сквозного соединения для каждого входного порта может быть установлен или в 1=yes
или в 0=no
. Это должно быть установлено в 1, если входной параметр, u
, используется в стандартной программе mdlGetTimeOfNextVarHit
или mdlOutputs
. Установка прямого флага сквозного соединения к 0 говорит механизму Simulink®, что u
не используется ни в одной из этих стандартных программ S-функции. Нарушение этого приводит к непредсказуемым результатам.
Тип данных входного порта, если не double
по умолчанию
Используйте
, чтобы установить тип данных входного порта. Если вы хотите, чтобы тип данных порта зависел от типа данных порта, с которым это соединяется, задайте тип данных как ssSetInputPortDataType
DYNAMICALLY_TYPED
. В этом случае необходимо обеспечить реализации
и mdlSetInputPortDataType
методов
, чтобы позволить типу данных быть установленным правильно во время распространения сигнала.mdlSetDefaultPortDataTypes
Числовой тип входного порта, если порт принимает сигналы с комплексным знаком
Используйте
, чтобы установить числовой тип входного порта. Если вы хотите, чтобы числовой тип порта зависел от числового типа порта, с которым это соединяется, задайте числовой тип как ssSetInputPortComplexSignal
COMPLEX_INHERITED
. В этом случае необходимо обеспечить реализации
и mdlSetInputPortComplexSignal
методов
, чтобы позволить числовому типу быть установленным правильно во время распространения сигнала.mdlSetDefaultPortComplexSignals
Можно сконфигурировать дополнительные свойства входного порта с помощью других макросов S-функции. Смотрите Порты Ввода и вывода в разделе “SimStruct Macros and Functions Listed by Usage” для получения дополнительной информации.
Метод mdlInitializeSizes
должен задать количество портов прежде, чем установить любые свойства. Если это пытается установить свойство порта, который не существует, это получает доступ к недопустимой памяти, и нарушение сегментации происходит.
Можно установить размерности входного порта с помощью одних из следующих макросов:
Если входной сигнал должен быть одномерным, и шириной входного порта является w
, использовать
ssSetInputPortWidth
(S, inputPortIdx, w)
Если входной сигнал должен быть матрицей размерности m
-by-n
, использовать
ssSetInputPortMatrixDimensions
(S, inputPortIdx, m, n)
В противном случае, если входной сигнал может иметь или одну или две размерности, использовать
ssSetInputPortDimensionInfo
(S, inputPortIdx, dimsInfo)
Можно использовать эту функцию для полностью или частично инициализировать размерности порта (см. следующий раздел).
Если ваша S-функция не требует, чтобы ее входные сигналы имели определенные размерности, можно установить размерность входных портов совпадать с размерностью сигналов, соединенных с ними.
Динамически определять размеры входного порта:
Задайте некоторых или все размерности входного порта, как динамически измерено в mdlInitializeSizes
.
Если входной порт может принять сигнал размерности, использовать
ssSetInputPortDimensionInfo(S, inputPortIdx, DYNAMIC_DIMENSION)
установить размерность входного порта.
Если входной порт может принять только векторные (1D) сигналы, но сигналы могут иметь любой размер, использовать
ssSetInputPortWidth(S, inputPortIdx, DYNAMICALLY_SIZED)
задавать размерность входного порта.
Если входной порт может принять только матричные сигналы, но может принять какую-либо строку или размер столбца, использовать
ssSetInputPortMatrixDimensions(S, inputPortIdx, DYNAMICALLY_SIZED, DYNAMICALLY_SIZED)
Предоставьте метод
, который устанавливает размерности входного порта к размеру сигнала, соединенного с ним.mdlSetInputPortDimensionInfo
Механизм Simulink вызывает этот метод во время распространения сигнала, когда это определило размерность сигнала, соединенного с входным портом.
Предоставьте метод mdlSetDefaultPortDimensionInfo
, который устанавливает размерности портов блока к значению по умолчанию. Смотрите sfun_dynsize.c
для примера, который реализует этот макрос.
Механизм вызывает этот метод во время распространения сигнала, когда это не может определить размерность сигнала, соединенного с некоторыми или всеми входными портами блока. Это может произойти, например, если входной порт не связан. Если S-функция не предоставляет этот метод, стандартная программа распространения сигнала устанавливает размерность портов блока к 1D скаляру.
Следующий код в mdlInitializeSizes
конфигурирует S-функцию с двумя входными портами. Смотрите Порты Ввода и вывода в разделе “SimStruct Macros and Functions Listed by Usage” для получения дополнительной информации о макросах, используемых в этом примере.
if (!ssSetNumInputPorts(S, 2)) return; for (i = 0; i < 2; i++) { /* Input has direct feedthrough */ ssSetInputPortDirectFeedThrough(S, i, 1); /* Input is a real signal */ ssSetInputPortComplexSignal(S, i, COMPLEX_NO); /* Input is a dynamically sized 2-D matrix */ ssSetInputPortMatrixDimensions(S ,i, DYNAMICALLY_SIZED, DYNAMICALLY_SIZED); /* Input inherits its sample time */ ssSetInputPortSampleTime(S, i,INHERITED_SAMPLE_TIME); /* Input signal must be contiguous */ ssSetInputPortRequiredContiguous(S, i, 1); /* The input port cannot share memory */ ssSetInputPortOverWritable(S, i, 0); }
Во время распространения сигнала механизм Simulink вызывает макрос mdlSetInputPortDimensionInfo
этой S-функции, чтобы инициализировать размерности входного порта. В этом примере mdlSetInputPortDimensionInfo
устанавливает входные размерности на размерности кандидата, переданные макросу механизмом.
#if defined(MATLAB_MEX_FILE) #define MDL_SET_INPUT_PORT_DIMENSION_INFO static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo) { if(!ssSetInputPortDimensionInfo(S, port, dimsInfo)) return; } #endif
Для примера, который конфигурирует S-функцию с несколькими портами ввода и вывода, откройте модель Simulink sfcndemo_sfun_multiport
и осмотрите S-функцию sfun_multiport.c
c.
Чтобы создать и сконфигурировать выходные порты, метод mdlInitializeSizes
должен сначала задать количество выходных портов S-функции, с помощью ssSetNumOutputPorts
. Затем для каждого выходного порта метод должен задать
Размерности выходного порта
Можно установить размерности выходного порта с помощью одних из следующих макросов:
Если вы хотите, чтобы размерности порта зависели от блочной возможности соединения, установите размерности на DYNAMIC_DIMENSIONS
при использовании ssSetOutputPortDimensionInfo
или на DYNAMICALLY_SIZED
для всех других макросов. S-функция должна затем обеспечить
и mdlSetOutputPortDimensionInfo
методы
, чтобы гарантировать, что размерности выходного порта установлены в правильные значения в генерации кода.mdlSetDefaultPortDimensionInfo
Тип данных выходного порта
Используйте
, чтобы установить тип данных выходного порта. Если вы хотите, чтобы тип данных порта зависел от блочной возможности соединения, задайте тип данных как ssSetOutputPortDataType
DYNAMICALLY_TYPED
. В этом случае необходимо обеспечить реализации
и mdlSetOutputPortDataType
методов
, чтобы позволить типу данных быть установленным правильно во время распространения сигнала.mdlSetDefaultPortDataTypes
Числовой тип выходного порта, если выходы порта сигналы с комплексным знаком
Используйте
, чтобы установить числовой тип выходного порта. Если вы хотите, чтобы числовой тип порта зависел от числового типа порта, с которым это соединяется, задайте числовой тип как ssSetOutputPortComplexSignal
COMPLEX_INHERITED
. В этом случае необходимо обеспечить реализации
и mdlSetOutputPortComplexSignal
методов
, чтобы позволить числовому типу быть установленным правильно во время распространения сигнала.mdlSetDefaultPortComplexSignals
Смотрите Входные порты Создания для S-функций C для примера, показывающего, как инициализировать порт S-входного-параметра-функции. Вы используете ту же процедуру, чтобы инициализировать выходные порты S-функции, но с соответствующим макросом выходного порта.
S-функция Level 2 MATLAB® использует скалярные правила расширения по умолчанию, если порты ввода и вывода заданы, как динамически измерено (см. Скалярное Расширение Вводов и Параметров в Использовании Simulink).
Со скалярным расширением на S-функция метод mdlInitializeSizes
должен указать, что порты ввода и вывода динамически измерены. Механизм Simulink использует метод по умолчанию, чтобы установить размерности портов ввода и вывода. Если блок имеет больше чем два входных параметра, входные сигналы могут быть скалярными или широкими сигналами, где широкие сигналы у всех есть то же число элементов. В этом случае механизм устанавливает размерности выходных портов к ширине широких входных сигналов и расширяет любые скалярные входные параметры до этой ширины. Если широкие входные параметры управляются 1D и 2D векторами, вывод является 2D векторным сигналом, и скалярные входные параметры расширены до 2D векторного сигнала.
Если скалярное расширение не включено, механизм принимает, что все порты (порты ввода и вывода) должны иметь те же размерности, и это устанавливает все размерности порта на те же размерности, заданные одним из ведущих блоков.
Механизм игнорирует скалярную опцию расширения, если S-функция задает или управляет размерностями своих портов ввода и вывода или путем инициализации размерностей в mdlInitializeSizes
, использования mdlSetInputPortWidth
и mdlSetOutputPortWidth
, или использования mdlSetInputPortDimensionInfo
, mdlSetOutputPortDimensionInfo
и mdlSetDefaultPortDimensionInfo
.
Лучший способ понять, как использовать скалярное расширение, состоит в том, чтобы считать пример sfcndemo_sfun_multiport
. Эта модель содержит три Блока s-function, каждого с несколькими входными портами. S-функция sfun_multiport.c
, используемый в этих блоках, устанавливает опцию SS_OPTION_ALLOW_INPUT_SCALAR_EXPANSION
в своем методе mdlInitializeSizes
, позволяя скалярное расширение входных параметров. S-функция указывает, что ее вводы и выводы динамически измерены. Поэтому во время распространения сигнала, механизм устанавливает ширину входных портов к ширине сигнала, соединенного с портом и шириной выходных портов к ширине любого широкого входного сигнала. Метод mdlOutputs
выполняет поэлементно сумма на входных сигналах, расширяя любые скалярные входные параметры, по мере необходимости.
/* Calculate an element-by-element sum of the input signals. yWidth is the width of the output signal. */ for (el = 0; el < yWidth; el++) { int_T port; real_T sum = 0.0; for (port = 0; port < nInputPorts; port++) { /* Get the input signal value */ InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,port); if (el < ssGetInputPortWidth(S,port)) { /* Input is a wide signal. Use specific element */ sum = sum + ((real_T)signs[port] * (*uPtrs[el])); } else { /* Use the scalar value to expand the signal */ sum = sum + ((real_T)signs[port] * (*uPtrs[0])); } } }