Данные MATLAB ® представлены какmxArrays на языке C/C + +. mxArray структура обычно содержит тип, измерение, данные, тип данных, разреженность, а также номера полей и полей массива MATLAB. В S-функциях значения Pass Dialog Parameters to S-Functions, оцениваемые в MATLAB, переносятся в Simulink ® как mxArray. Список функций см. в разделе C Matrix API.
S-функции считывают данные MATLAB главным образом для следующих целей:
Доступ к параметрам диалогового окна блока с помощью mxArrays
Передача аргументов функции MATLAB с помощью mexCallMATLAB
mxArray МанипуляцияВы можете управлять mxArrays в S-функциях с использованием стандартных функций MATLAB API. В общем случае, если ваша S-функция объявлена свободной от исключений путем передачи SS_OPTION_EXCEPTION_FREE_CODE опция для ssSetOptions (см. Свободный код исключения в разделе Обработка ошибок в S-функциях), он должен избегать функций MATLAB API, которые вызывают исключения (например, прыжок в длину), такие как mxCreateDoubleMatrix. В противном случае S-функция может использовать любую из перечисленных функций.
Примечание
Параметры S-функции доступны только для чтения в алгоритме S-функции. Изменить значения параметров можно с помощью диалогового окна или маски S-функционального блока.
Если у вас есть Simulink Coder™, он поддерживает подмножество mxArray функции манипуляции при генерации неинлинного кода для S-функции. Список поддерживаемых функций см. в разделе Запись неинлинированной S-функции (Simulink Coder).
Вызовы макроса ssGetSFcnParam возврат указателя на mxArray, который может использоваться с mxArray функции манипуляции. Если S-функция содержит параметры S-функции, используйте mxArray функции манипуляции в mdlCheckParameters метод проверки значений параметров S-функции. См. S-функцию sfun_runtime3.c для примера
В этой S-функции следующие строки проверяют, что первый параметр S-функции является символьным массивом длиной больше или равной двум.
if (!mxIsChar(ssGetSFcnParam(S, 0)) ||
(nu=mxGetNumberOfElements(ssGetSFcnParam(S, 0))) < 2) {
ssSetErrorStatus(S,"1st parameter to S-function must be a "
"string of at least 2 '+' and '-' characters");
return;
}mxArrays Использование 32-разрядных APIЗапись программ C/C + +, работающих с MATLABmxArray структура данных, используйте API матрицы C. API матрицы C поддерживают 32-разрядное и 64-разрядное индексирование. По умолчанию S-функции создаются с использованием 32-разрядных API. Установите флажок Обновить файлы MEX для использования 64-Bit API, чтобы узнать, как обновить существующие файлы MEX.
Для проверки использования 32-разрядных API можно запустить помощник по обновлению S-функций. На вкладке Моделирование (Modeling) выберите Мастер модели (Model Advisor) > Помощник по обновлению (Upgrade Advisor).
При создании кода с помощью -largeArrayDims и ваш код заполняет ssParamRec поле измерения структуры с mxArray размеры, начиная с R2018a, вы больше не можете привести возвращаемое значение mxGetDimensions в int_T pointer потому что mxGetDimensions теперь возвращает size_T указатель на 64-разрядных платформах. В качестве обходного решения создайте временную копию типа int_T и назначить его dims поле ssParamRec структура.
| Заменить: | С: |
|---|---|
ssParamRec p;
p.dims = (int_T *) mxGetDimensions(ssGetSFcnParam(S, 0));
// Set up other fields of p
if (!ssSetRunTimeParamInfo(S, 0, &p)) {
free(dims);
return;
}
free(dims); // free memory allocated for dimensions
|
ssParamRec p;
const mxArray* mxPrm = ssGetSFcnParam(S, 0);
const mwSize* mxDims = mxGetDimensions(mxPrm);
const mwSize mxNumDims = mxGetNumberOfDimensions(mxPrm);
mwSize idx;
int_T * dims = malloc(sizeof(int)*mxNumDims);
for (idx=0; idx < mxNumDims; idx++)
{
dims[idx] = mxDims[idx];
}
p.dims = dims;
// Set up other fields of p
if (!ssSetRunTimeParamInfo(S, 0, &p)) {
free(dims);
return;
}
free(dims); // free memory allocated for dimensions
|
mxArrays Использование перемежающегося комплексного представленияДо версии MATLAB 9.4 (R2018a), mxArrays использовал отдельное комплексное представление, где действительная и мнимая части комплексного числа хранились отдельно. Начиная с версии 9.4 (R2018a), MATLAB использует перемежающееся представление для хранения комплексных данных, где действительная и мнимая части комплексных чисел хранятся вместе. Для управления S-функциями mxArrays, больше нет необходимости преобразовывать данные из отдельного в перемежающийся комплекс. Дополнительные сведения об обновлении кода см. в разделе MATLAB Support for Interleaved Complex API в разделе Функции MEX.
Примечание
Для хранения сложных данных для входных и выходных сигналов или DWorks Simulink использует чередующееся представление.
Чтобы автоматически проверить S-функции на возможные проблемы с перемежающимися сложными данными, на вкладке Моделирование (Modeling) выберите Мастер модели (Model Advisor) > Помощник по обновлению (Upgrade Advisor). В окне Помощник по обновлению выберите Проверить модель на наличие проблем обновления S-функций.
Следующий пример кода копирует значение параметра из mxArray к выходу S-функции. В этом примере измерения, тип данных и сложность параметра и выходного аргумента гарантируются одинаковыми. Например, если параметр является комплексным, выходной сигнал является комплексным. Если параметр является реальным, то выходной сигнал является реальным. В приведенном ниже примере тип данных параметра и вывода является двойным (real_T). Перед R2018a можно использовать mxGetPr и mxGetPr для копирования действительной и мнимой частей сложных данных по отдельности. С перемежающимся комплексным представлением можно использовать memcpy, которая представляет собой инструкцию в единственном экземпляре.
| Заменить: | С: |
|---|---|
real_T *y = ssGetOutputPortRealSignal(S,0);
boolean_T yIsComplex = ssGetOutputPortComplexSignal(S, 0) == COMPLEX_YES;
int_T yWidth = ssGetOutputPortWidth(S,0);
const real_T *pr = mxGetPr(ssGetSFcnParam(S, 0));
const real_T *pi = mxGetPi(ssGetSFcnParam(S, 0));
int i;
for (i = 0; i < yWidth; i++) {
int_T idx = (yIsComplex) ? 2*i : i;
y[idx] = pr[idx];
if(yIsComplex){
y[idx+1] = pi[idx];
}
}
|
real_T *y = ssGetOutputPortRealSignal(S,0);
boolean_T yIsComplex = ssGetOutputPortComplexSignal(S, 0) == COMPLEX_YES;
int_T yWidth = ssGetOutputPortWidth(S,0);
mxComplexDouble *pc;
mxDouble *pr;
if (yIsComplex) {
pc = mxGetComplexDoubles(ssGetSFcnParam(S, 0));
memcpy(y, pc, yWidth*sizeof(mxComplexDouble));
} else {
pr = mxGetDoubles(ssGetSFcnParam(S, 0));
memcpy(y, pr, yWidth*sizeof(mxDouble));
}
|
[a]
| |
S-функция | Построитель S-функций