Можно использовать следующее: SimStruct макросы в mdlInitializeSizes способ определения области и возможности повторного использования памяти, используемой для портов ввода и вывода S-функции:
ssSetInputPortOptimOpts: Укажите область и возможность повторного использования памяти, выделенной входному порту S-функции.
ssSetOutputPortOptimOpts: Укажите область и возможность повторного использования памяти, выделенной выходному порту S-функции.
ssSetInputPortOverWritable: Укажите, может ли один из входных портов S-функции быть перезаписан одним из его выходных портов.
ssSetOutputPortOverwritesInputPort: Укажите, может ли выходной порт совместно использовать буфер памяти с входным портом.
Ввод или вывод объявляется локальным или глобальным и указывается на возможность повторного использования, передавая одну из следующих четырех опций в ssSetInputPortOptimOpts и ssSetOutputPortOptimOpts макросы:
SS_NOT_REUSABLE_AND_GLOBAL: Указывает, что входные и выходные порты хранятся в отдельных ячейках памяти в глобальной блочной структуре ввода и вывода.
SS_NOT_REUSABLE_AND_LOCAL: Указывает, что генератор кода может объявлять отдельные локальные переменные для портов ввода и вывода.
SS_REUSABLE_AND_LOCAL: Указывает, что генератор кода может повторно использовать одну локальную переменную для этих портов ввода и вывода.
SS_REUSABLE_AND_GLOBAL: Указывает, что эти входные и выходные порты хранятся в одном элементе в глобальной блочной структуре ввода и вывода.
Примечание
Пометка входного или выходного порта как локальной переменной не означает, что генератор кода использует локальную переменную в сгенерированном коде. Если функция S обращается к входам и выходам только в ее mdlOutputs , генератор кода объявляет входы и выходы как локальные переменные. Однако, если входы и выходы используются в другом месте S-функции, генератор кода включает их в структуру ввода и вывода глобального блока.
Параметр многократного использования указывает, можно ли перезаписать память, связанную с портом ввода или вывода. Для повторного использования памяти портов ввода и вывода:
Укажите порты, которые можно повторно использовать с помощью SS_REUSABLE_AND_LOCAL или SS_REUSABLE_AND_GLOBAL опции в ssSetInputPortOptimOpts и ssSetOutputPortOptimOpts макросы.
Укажите, что память входного порта перезаписывается с помощью ssSetInputPortOverWritable.
Если функция S имеет несколько портов ввода и вывода, используйте ssSetOutputPortOverwritesInputPort для указания, какие выходные и входные порты совместно используют память.
В следующем примере показано, как различные параметры области и многократного использования влияют на созданный код. Следующая модель содержит блок S-функции, указывающий на 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); | /* 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); | /* Block signals (auto storage) */
typedef struct {
real_T SFunction[2];
} BlockIO_sl_directlook; /* 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); | /* 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); | /* Block signals (auto storage) */
typedef struct {
real_T SineWave[2];
real_T SFunction[2];
} BlockIO_sl_directlook; /* 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] |