Чтобы создать и сконфигурировать входные порты, mdlInitializeSizes
метод должен сначала указать количество входных портов S-функции, используя ssSetNumInputPorts
. Затем для каждого входного порта метод должен задать
Размерности входного порта (см. «Инициализация размеров Input port»)
Если вы хотите, чтобы ваша S-функция унаследовала ее размерность от порта, с которым она связана, необходимо указать, что порт имеет динамический размер в mdlInitializeSizes
(см. раздел Динамическое изменение размеров входного порта).
Позволяет ли входной порт скалярное расширение входов (см. Скалярное расширение входных параметров)
Имеет ли порт входа прямые сквозные соединения, использование ssSetInputPortDirectFeedThrough
Порт имеет прямое сквозное соединение, если вход используется в mdlOutputs
или mdlGetTimeOfNextVarHit
функций. Флаг прямой передачи для каждого входного порта может быть установлен на любое 1=yes
или 0=no
. Оно должно быть установлено равным 1, если вход, u
, используется в mdlOutputs
или mdlGetTimeOfNextVarHit
стандартная программа. Установка флага прямой передачи равного 0 говорит Simulink® двигатель, который u
не используется ни в одной из этих стандартных программ S-функций. Нарушение этого приводит к непредсказуемым результатам.
Тип данных входного порта, если не тип по умолчанию double
Использовать
для установки типа данных порта входа. Если необходимо, чтобы тип данных порта зависел от типа данных порта, к которому он подключен, укажите тип данных следующим ssSetInputPortDataType
DYNAMICALLY_TYPED
. В этом случае вы должны предоставить реализации
и mdlSetInputPortDataType
методы, позволяющие правильно задать тип данных во время распространения сигнала.mdlSetDefaultPortDataTypes
Числовой тип входного порта, если порт принимает комплексные сигналы
Использовать
для установки числового типа порта входа. Если необходимо, чтобы числовой тип порта зависел от числового типа порта, к которому он подключен, задайте числовой тип следующим ssSetInputPortComplexSignal
COMPLEX_INHERITED
. В этом случае вы должны предоставить реализации
и mdlSetInputPortComplexSignal
методы, позволяющие правильно задать числовой тип во время распространения сигнала.mdlSetDefaultPortComplexSignals
Можно сконфигурировать дополнительные свойства входного порта, используя другие макросы S-функций. Смотрите Входные и Выходные Порты в разделе «Макросы SimStruct и функции, перечисленные при использовании» для получения дополнительной информации.
Примечание
The 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)
для установки размерности порта входа.
Если вход порт может принимать только вектор (1-D) сигналы, но сигналы могут быть любого размера, используйте
ssSetInputPortWidth(S, inputPortIdx, DYNAMICALLY_SIZED)
для определения размерности входного порта.
Если входной порт может принимать только матричные сигналы, но может принимать любой размер строки или столбца, используйте
ssSetInputPortMatrixDimensions(S, inputPortIdx, DYNAMICALLY_SIZED, DYNAMICALLY_SIZED)
Предоставить
метод, который устанавливает размерности входного порта равным размеру сигнала, соединенного с ним.mdlSetInputPortDimensionInfo
Механизм Simulink вызывает этот метод во время распространения сигнала, когда он определил размерность сигнала, соединенного с портом входа.
Предоставить mdlSetDefaultPortDimensionInfo
метод, который устанавливает размерности портов блока в значение по умолчанию. См. sfun_dynsize.c
для примера, который реализует этот макрос.
Механизм вызывает этот метод во время распространения сигнала, когда он не может определить размерность сигнала, соединенного с некоторыми или всеми входными портами блока. Это может произойти, пример, если вход порт не подключен. Если S-функция не предоставляет этот метод, стандартная программа распространения сигнала устанавливает размерность портов блока 1-D скаляром.
Следующий код в mdlInitializeSizes
конфигурирует S-функцию с двумя входными портами. Смотрите Входные и Выходные Порты в разделе «Макросы SimStruct и функции, перечисленные по использованию» для получения дополнительной информации о макросах, используемых в этом примере.
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
.
Чтобы создать и сконфигурировать выходные порты, 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-функции. Это осуществляется путем установки каждого элемента расширенного сигнала на значение скаляра входа.
A Level-2 MATLAB® S-функция использует скалярные правила расширения по умолчанию, если входной и выходной порты заданы как динамически определенные (см. «Скалярное расширение входов и параметров в использовании Simulink»).
При включенном скалярном расширении S-функция mdlInitializeSizes
метод должен указать, что входной и выходной порты имеют динамический размер. Механизм Simulink использует метод по умолчанию, чтобы задать размерности входного и выходного портов. Если блок имеет более двух входов, входные сигналы могут быть скалярными или широкими сигналами, где все широкие сигналы имеют одинаковое количество элементов. В этом случае двигатель устанавливает размерности выходных портов на ширину широких входных сигналов и расширяет любые скалярные входы до этой ширины. Если широкие входы управляются 1-D и 2-D векторами, выход является 2-D векторным сигналом, и скалярные входы расширяются до 2-D векторного сигнала.
Если скалярное расширение не включено, двигатель принимает, что все порты (входные и выходные порты) должны иметь одинаковые размерности, и он устанавливает все размерности портов те же самые размерности, заданные одним из ведущих блоков.
Примечание
Механизм игнорирует опцию скалярного расширения, если S-функция задает или управляет размерностями своих входных и выходных портов либо путем инициализации размерностей в mdlInitializeSizes
, использование mdlSetInputPortWidth
и mdlSetOutputPortWidth
, или использование mdlSetInputPortDimensionInfo
, mdlSetOutputPortDimensionInfo
, и mdlSetDefaultPortDimensionInfo
.
Лучший способ понять, как использовать скалярное расширение, это рассмотреть пример sfcndemo_sfun_multiport
. Эта модель содержит три блоков s-function, каждый с несколькими входными портами. S-функция sfun_multiport.c
используется в этих блоках, устанавливает SS_OPTION_ALLOW_INPUT_SCALAR_EXPANSION
опция в своей mdlInitializeSizes
способ, позволяющий скалярное расширение входов. S-функция задает, что ее входы и выходы динамически. Поэтому во время распространения сигнала двигатель устанавливает ширину входных портов на ширину сигнала, соединенного с портом, и ширину выходных портов на ширину любого широкого входного сигнала. The 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])); } } }
Если вы разрабатываете маскированные мультипортовые блоки s-function, количество портов которых изменяется на основе некоторого параметра и хотите поместить их в библиотеку Simulink, необходимо указать, что маска изменяет внешний вид блока. Для этого выполните команду
set_param(blockname,'MaskSelfModifiable','on')
в командной строке MATLAB перед сохранением библиотеки, где blockname
- полный путь к блоку. Отказ, что маска изменяет внешний вид блока, означает, что экземпляр блока в модели возвращается к количеству портов в библиотеке каждый раз, когда вы загружаете модель или обновляете библиотечную ссылку.