MATLAB® данные представлены как mxArrays
на языке C/C + +. The mxArray
структура обычно содержит тип, размерность, данные, тип данных, разреженность, а также номера полей и полей массива MATLAB. В S-функциях Передайте параметры диалога в S-функции значения, оцененные в MATLAB, передаются в Simulink® как mxArray
. Список функций см. в API C Matrix.
S-функции считывают данные MATLAB в основном для следующих целей:
Доступ к параметрам диалогового окна блоков с помощью mxArrays
Передайте аргументы в или из функции MATLAB с помощью mexCallMATLAB
mxArray
МанипуляцияМожно манипулировать mxArrays
в S-функциях с использованием стандартных функций MATLAB API. В целом, если ваша S-функция объявлена свободной исключением путем передачи SS_OPTION_EXCEPTION_FREE_CODE
опция для ssSetOptions
(см. Исключение Free Code в Handle Errors in S-Functions), он должен избегать функций MATLAB API, которые выдают исключения (то есть, скачок в длину), таких как mxCreateDoubleMatrix
. В противном случае S-функция может использовать любую из перечисленных функций.
Примечание
Параметры S-функции доступны только для чтения в алгоритме S-функции. Вы можете изменить значения параметров в диалоговом окне Блока s-function или маске.
Если у вас есть Simulink Coder™, он поддерживает подмножество mxArray
функции манипуляции при генерации неинстрированного кода для S-функции. Список поддерживаемых функций см. в Write Noninlined S-Function (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 + +, которые работают с MATLAB mxArray
структура данных, используйте матричные API на C. Матричные API на C поддерживают 32-разрядную и 64-разрядную индексацию. По умолчанию ваши S-функции создаются с использованием 32-битных API. Проверьте Upgrade MEX Files, чтобы использовать 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 для Interleaved Complex API в MEX-функции для получения дополнительной информации о том, как обновить ваш код.
Примечание
Чтобы хранить комплексные данные для входных и выходных сигналов или DWorks, Simulink использует чередующееся представление.
Чтобы автоматически проверить свои S-функции на потенциальные проблемы перемеженных комплексных данных, на вкладке Modeling, выберите Model Advisor > Upgrade Advisor. В окне Upgrade Advisor выберите Check model for S-function upgrade issues.
Следующая выборка кода копирует значение параметров из mxArray
на выход S-функции. В этом примере размерности, тип данных и сложность параметра и выходного аргумента гарантируются одинаковыми. Для примера, если параметр комплексен, выход сигнал комплексен. Если параметр вещественный, выходной сигнал действителен. Для примера ниже, тип данных и параметра, и выхода является double (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-Function | S-Function Builder