exponenta event banner

Порты ввода и вывода

Создание входных портов для C S-функций

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

  • Размеры входного порта (см. раздел Инициализация размеров входного порта)

    Если требуется, чтобы 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, перечисленные по использованию».

Примечание

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

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

Размеры портов ввода можно задать с помощью одного из следующих макросов:

  • Если входной сигнал должен быть одномерным, а ширина входного порта равна w, использовать

    ssSetInputPortWidth(S, inputPortIdx, w)
    
  • Если входной сигнал должен быть матрицей размерности mоколо-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 скалярным.

Пример: Определение нескольких портов ввода S-функций

Следующий код в 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 вызывает эту S-функцию mdlSetInputPortDimensionInfo для инициализации размеров входного порта. В этом примере: 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 S-функций

Для создания и конфигурирования портов вывода, 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 ® S использует правила скалярного расширения по умолчанию, если входные и выходные порты задаются динамически (см. раздел Скалярное расширение входов и параметров в разделе Использование Simulink).

При включенном скалярном расширении S-функция mdlInitializeSizes метод должен определять динамический размер входного и выходного портов. Модуль Simulink использует метод по умолчанию для задания размеров портов ввода и вывода. Если блок имеет более двух входов, входные сигналы могут быть скалярными или широкими, где все широкие сигналы имеют одинаковое количество элементов. В этом случае механизм устанавливает размеры выходных портов на ширину широких входных сигналов и расширяет любые скалярные входы на эту ширину. Если широкие входы управляются векторами 1-D и 2-D, то выход является сигналом вектора 2-D, а скалярные входы расширяются до сигнала вектора 2-D.

Если скалярное расширение не включено, модуль предполагает, что все порты (входной и выходной порты) должны иметь одинаковые размеры, и устанавливает для всех размеров портов одинаковые размеры, заданные одним из управляющих блоков.

Примечание

Модуль игнорирует опцию скалярного расширения, если S-функция определяет или управляет размерами своего входного и выходного портов, либо инициализируя размеры в mdlInitializeSizes, использование mdlSetInputPortWidth и mdlSetOutputPortWidth, или использование mdlSetInputPortDimensionInfo, mdlSetOutputPortDimensionInfo, и mdlSetDefaultPortDimensionInfo.

Лучший способ понять, как использовать скалярное расширение, это рассмотреть пример sfcndemo_sfun_multiport. Эта модель содержит три S-функциональных блока, каждый из которых имеет несколько входных портов. 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]));
      }
   }
}

Маскированные мультипортовые S-функции

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

  set_param(blockname,'MaskSelfModifiable','on')

в командной строке MATLAB перед сохранением библиотеки, где blockname - полный путь к блоку. Если не указать, что маска изменяет внешний вид блока, экземпляр блока в модели возвращается к количеству портов в библиотеке при загрузке модели или обновлении связи с библиотекой.