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

Создание Input port для S-функций C

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

  • Размерности входного порта (см. Инициализацию Размерности Input port),

    Если вы хотите, чтобы ваша S-функция наследовала свою размерность от порта, до которого она соединяется, необходимо указать, что порт динамически измерен в mdlInitializeSizes (см. калибровку Input port динамически).

  • Позволяет ли входной порт скалярное расширение входных параметров (см. Скалярное Расширение Входных параметров),

  • Имеет ли входной порт прямое сквозное соединение, с помощью 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 Macros and Functions Listed by Usage” для получения дополнительной информации.

Примечание

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

Инициализация размерностей Input port

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

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

    ssSetInputPortWidth(S, inputPortIdx, w)
    
  • Если входной сигнал должен быть матрицей размерности m- nИспользование

    ssSetInputPortMatrixDimensions(S, inputPortIdx, m, n)
    
  • В противном случае, если входной сигнал может иметь или одну или две размерности, использовать

    ssSetInputPortDimensionInfo(S, inputPortIdx, dimsInfo)
    

    Можно использовать эту функцию для полностью или частично инициализировать размерности порта (см. следующий раздел).

Калибровка Input port динамически

Если ваша 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 скаляру.

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

Следующий код в 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.

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

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

  • Размерности выходного порта

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

    Если вы хотите, чтобы размерности порта зависели от возможности соединения блока, установите размерности на DYNAMIC_DIMENSIONS при использовании ssSetOutputPortDimensionInfo или к DYNAMICALLY_SIZED для всех других макросов. S-функция должна затем обеспечить mdlSetOutputPortDimensionInfo и mdlSetDefaultPortDimensionInfo методы, чтобы гарантировать, что размерности выходного порта установлены в правильные значения в генерации кода.

  • Тип данных выходного порта

    Использование ssSetOutputPortDataType установить тип данных выходного порта. Если вы хотите, чтобы тип данных порта зависел от возможности соединения блока, задайте тип данных как DYNAMICALLY_TYPED. В этом случае необходимо обеспечить реализации mdlSetOutputPortDataType и mdlSetDefaultPortDataTypes методы, чтобы позволить типу данных, который будет установлен правильно во время распространения сигнала.

  • Числовой тип выходного порта, если выходы порта сигналы с комплексным знаком

    Использование ssSetOutputPortComplexSignal установить числовой тип выходного порта. Если вы хотите, чтобы числовой тип порта зависел от числового типа порта, с которым это соединяется, задайте числовой тип как COMPLEX_INHERITED. В этом случае необходимо обеспечить реализации mdlSetOutputPortComplexSignal и mdlSetDefaultPortComplexSignals методы, чтобы позволить числовому типу, который будет установлен правильно во время распространения сигнала.

Смотрите Создание Input port для S-функций C для примера, показывающего, как инициализировать порт S-входного-параметра-функции. Вы используете ту же процедуру, чтобы инициализировать выходные порты 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]));
      }
   }
}

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

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

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

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