S-функции, которые задают возможности и переиспользуемость

Можно использовать следующие SimStruct макросы в mdlInitializeSizes метод для определения возможностей и переиспользуемости памяти, используемой для входных и выходных портов вашей S-функции:

  • ssSetInputPortOptimOpts: Укажите возможности и переиспользуемость памяти, выделенной входному порту S-функции.

  • ssSetOutputPortOptimOpts: Укажите возможности и переиспользуемость памяти, выделенной выходному порту S-функции.

  • ssSetInputPortOverWritable: Укажите, можно ли перезаписать один из входа портов вашей S-функции одним из его выхода портов.

  • ssSetOutputPortOverwritesInputPort: Укажите, может ли порт выхода совместно использовать буфер памяти с портом входа.

Вы объявляете вход или выход как локальный или глобальный и указываете на его переиспользуемость, передав один из следующих четырёх опций ssSetInputPortOptimOpts и ssSetOutputPortOptimOpts макросы:

  • SS_NOT_REUSABLE_AND_GLOBAL: Указывает, что входы и выход порты хранятся в отдельных местах памяти в глобальных блочных входах и структуре output.

  • SS_NOT_REUSABLE_AND_LOCAL: Указывает, что генератор кода может объявить индивидуума локальные переменные для входа и выходных портов.

  • SS_REUSABLE_AND_LOCAL: Указывает, что генератор кода может повторно использовать одну локальную переменную для этих входных и выходных портов.

  • SS_REUSABLE_AND_GLOBAL: Указывает, что эти входы и выход порты хранятся в одном элементе в глобальных блочных входах и структуре output.

Примечание

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

Параметр переиспользуемости указывает, можно ли перезаписать память, связанную с входом или выходом портом. Чтобы повторно использовать вход и выходного портов:

  1. Укажите, что порты переиспользуются с помощью SS_REUSABLE_AND_LOCAL или SS_REUSABLE_AND_GLOBAL опция в ssSetInputPortOptimOpts и ssSetOutputPortOptimOpts макросы.

  2. Укажите, что вход порта перезаписывается с помощью ssSetInputPortOverWritable.

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

В следующем примере показано, как различные параметры возможностей и переиспользуемости влияют на сгенерированный код. Следующая модель содержит блок s-function, указывающий на S-функцию C MEX matlabroot/ toolbox/simulink/simdemos/simfeatures/src/sfun_directlook.c, которая моделирует интерполяционную таблицу прямого 1-D.

Функции S mdlInitializeSizes метод объявляет вход порт переиспользуемым, локальным и перезаписываемым, а выход порт - переиспользуемым и локальным следующим образом:

static void mdlInitializeSizes(SimStruct *S)
{
/* snip */
    ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
    ssSetInputPortOverWritable(S, 0, TRUE);

/* snip */
    ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);

/* snip */
}

Сгенерированный код для этой модели сохраняет входные и выходные сигналы в одной локальной переменной rtb_SFunction, как показано на следующей выходной функции:

static void sl_directlook_output(int_T tid)
{
  /* local block i/o variables */
  real_T rtb_SFunction[2];

  /* Sin: '<Root>/Sine Wave' */
  rtb_SFunction[0] = sin(((real_T)sl_directlook_DWork.counter[0] +
    sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
    sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[0] +
    sl_directlook_P.SineWave_Bias;
  rtb_SFunction[1] = sin(((real_T)sl_directlook_DWork.counter[1] +
    sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
    sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[1] +
    sl_directlook_P.SineWave_Bias;

  /* S-Function Block: <Root>/S-Function */
  {
    const real_T *xData = &sl_directlook_P.SFunction_XData[0];
    const real_T *yData = &sl_directlook_P.SFunction_YData [0];
    real_T spacing = xData[1] - xData[0];
    if (rtb_SFunction[0] <= xData[0] ) {
      rtb_SFunction[0] = yData[0];
    } else if (rtb_SFunction[0] >= yData[20] ) {
      rtb_SFunction[0] = yData[20];
    } else {
      int_T idx = (int_T)( ( rtb_SFunction[0] - xData[0] ) / spacing );
      rtb_SFunction[0] = yData[idx];
    }

    if (rtb_SFunction[1] <= xData[0] ) {
      rtb_SFunction[1] = yData[0];
    } else if (rtb_SFunction[1] >= yData[20] ) {
      rtb_SFunction[1] = yData[20];
    } else {
      int_T idx = (int_T)( ( rtb_SFunction[1] - xData[0] ) / spacing );
      rtb_SFunction[1] = yData[idx];
    }
  }

  /* Outport: '<Root>/Out1' */
  sl_directlook_Y.Out1[0] = rtb_SFunction[0];
  sl_directlook_Y.Out1[1] = rtb_SFunction[1];
  UNUSED_PARAMETER(tid);
}

В этой таблице показаны изменения кода, сгенерированного для этой модели, при использовании типового целевого устройства в реальном времени (GRT). Каждая строка объясняет различные настройки для возможностей и переиспользуемости входных и выходных портов S-функции.

Возможности и переиспользуемостьS-функции mdlInitializeSizes кодСгенерированный код

Входы: Локальные, переиспользуемые, перезаписываемые

Выходы: Локальные, переиспользуемые

ssSetInputPortOptimOpts(S, 0,
SS_REUSABLE_AND_LOCAL);

ssSetInputPortOverWritable(S, 0,
TRUE);

ssSetOutputPortOptimOpts(S, 0,
SS_REUSABLE_AND_LOCAL);

The model.c файл объявляет локальную переменную в выходной функции.

/* local block i/o variables */
  real_T rtb_SFunction[2];

Входы: Глобальные, переиспользуемые, перезаписываемые

Выходы: Глобальные, переиспользуемые

ssSetInputPortOptimOpts(S, 0,
SS_REUSABLE_AND_GLOBAL);

ssSetInputPortOverWritable(S, 0,
TRUE);

ssSetOutputPortOptimOpts(S, 0,
SS_REUSABLE_AND_GLOBAL);

The model.h файл задает структуру блочных сигналов с одним элементом для хранения входных и выходных данных S-функции.

/* Block signals (auto storage) */
typedef struct {
  real_T SFunction[2];
} BlockIO_sl_directlook;

The model.c файл использует этот элемент структуры в вычислениях входных и выходных сигналов S-функции.

 /* Sin: '<Root>/Sine Wave' */
sl_directlook_B.SFunction[0] = sin ...
/* snip */
/*S-Function Block:<Root>/S-Function*/
{
const real_T *xData =
  &sl_directlook_P.SFunction_XData[0]

Входы: Локальные, не переиспользуемые

Выходы: Локальный, не переиспользуемый

ssSetInputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_LOCAL);

ssSetInputPortOverWritable(S, 0,
FALSE);

ssSetOutputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_LOCAL);

The model.c файл объявляет локальные переменные для входных и выходных входов S-функции в выходной функции

/* local block i/o variables */
  real_T rtb_SineWave[2];
  real_T rtb_SFunction[2];

Входы: Глобальные, не переиспользуемые

Выходы: Глобальные, не переиспользуемые

ssSetInputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_GLOBAL);

ssSetInputPortOverWritable(S, 0,
FALSE);

ssSetOutputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_GLOBAL);

The model.h файл задает структуру сигнала блока с отдельными элементами для хранения входных и выходных входов S-функции.

/* Block signals (auto storage) */
typedef struct {
  real_T SineWave[2];
  real_T SFunction[2];
} BlockIO_sl_directlook;

The model.c файл использует различные элементы этой структуры при вычислении входных и выходных параметров S-функции.

 /* Sin: '<Root>/Sine Wave' */
sl_directlook_B.SineWave[0] = sin ...
/* snip */
/*S-Function Block:<Root>/S-Function*/
{
const real_T *xData =
  &sl_directlook_P.SFunction_XData[0]

Похожие темы