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

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

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

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

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

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

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

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

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

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

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

Примечание

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

Установка возможности многократного использования указывает, может ли память, сопоставленная с портом ввода или вывода, быть перезаписана. К порту memory ввода и вывода повторного использования:

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

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

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

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

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

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);

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

/* 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);

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

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

Файл .c model использует этот элемент структуры в вычислениях сигналов ввода и вывода 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);

Файл .c model объявляет локальные переменные для ввода и вывода 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);

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

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

Файл .c model использует различные элементы в этой структуре при вычислении ввода и вывода 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]

Похожие темы