Можно использовать следующие 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-функции, генератор кода включает их в глобальную блочную входную и выходную структуру.
Параметр переиспользуемости указывает, можно ли перезаписать память, связанную с входом или выходом портом. Чтобы повторно использовать вход и выходного портов:
Укажите, что порты переиспользуются с помощью SS_REUSABLE_AND_LOCAL
или SS_REUSABLE_AND_GLOBAL
опция в ssSetInputPortOptimOpts
и ssSetOutputPortOptimOpts
макросы.
Укажите, что вход порта перезаписывается с помощью ssSetInputPortOverWritable
.
Если ваша S-функция имеет несколько входных и выходных портов, используйте ssSetOutputPortOverwritesInputPort
чтобы указать, какие выходные и входные порты совместно используют память.
В следующем примере показано, как различные параметры возможностей и переиспользуемости влияют на сгенерированный код. Следующая модель содержит блок s-function, указывающий на S-функцию C MEX
, которая моделирует интерполяционную таблицу прямого 1-D.matlabroot
/ toolbox/simulink/simdemos/simfeatures/src/sfun_directlook.c
Функции 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 /* 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 /* Block signals (auto storage) */ typedef struct { real_T SFunction[2]; } BlockIO_sl_directlook; The /* 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 /* 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 /* Block signals (auto storage) */ typedef struct { real_T SineWave[2]; real_T SFunction[2]; } BlockIO_sl_directlook; The /* 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] |