В дополнение к векторам DWork программное обеспечение Simulink® обеспечивает упрощенный набор векторов работы. В некоторых S-функциях они элементарные векторы работы могут предоставить более легкое решение, чем использование векторов DWork:
Векторы iWork хранят целочисленные данные.
Модель векторов режима обнуляет пересечения или другие функции, которые требуют одного вектора режима.
Векторы PWork хранят указатели на структуры данных, такие как те, которые соединяют интерфейсом с S-функцией к унаследованному коду, другому программному обеспечению или аппаратному приложению.
Векторы RWork хранят (действительные) данные с плавающей точкой.
Следующая таблица сравнивает каждый тип вектора работы к вектору DWork.
Тип вектора работы | Сравнение с вектором DWork | Как создать эквивалентный вектор DWork |
---|---|---|
IWork | Векторы iWork не могут быть настроены в сгенерированном коде. Кроме того, вам разрешают только один вектор IWork. | ssSetNumDWork(S,1); ssSetDWorkDataType(S, 0, SS_INT8); |
Режим | Векторы режима требуют большей памяти, чем векторы DWork, поскольку вектор режима всегда хранится integer тип данных. Кроме того, вам разрешают только один вектор Режима. | ssSetNumDWork(S,1); ssSetDWorkUsageType(S, 0, sSS_DWORK_USED_AS_MODE); ssSetDWorkDataType(S, 0, SS_INT8); |
PWork | В отличие от векторов DWork, векторы PWork нельзя назвать в сгенерированном коде. Кроме того, вам разрешают только один вектор PWork. | ssSetNumDWork(S,1); ssSetDWorkDataType(S, 0, SS_POINTER); |
RWork | Векторы RWork не могут быть настроены в сгенерированном коде. Кроме того, вам разрешают только один вектор RWork. | ssSetNumDWork(S,1); ssSetDWorkDataType(S, 0, SS_DOUBLE); |
Процесс для использования элементарных векторов работы похож на это для векторов DWork (см. Используя Векторы DWork в S-функциях MEX C.) Элементарные векторы работы имеют меньше свойств, таким образом, процесс инициализации более прост. Однако, если необходимо сгенерировать код для S-функции, S-функция становится более включенной чем тогда, когда с помощью векторов DWork.
Следующие шаги показывают, как настроить и использовать элементарные векторы работы. Смотрите Макросы Вектора Дополнительной работы для списка макросов, связанных с каждым шагом в следующем процессе.
В mdlInitializeSizes
, задайте размер векторов работы с помощью ssSetNum
макрос, например:X
Работа
ssSetNumPWork(S, 2);
Этот макрос указывает, сколько элементов вектор работы содержит, однако, механизм Simulink не выделяет память в это время.
S-функция может задержать определение длины векторов работы, пока вся информация о S-входных-параметрах-функции не доступна путем передачи значения DYNAMICALLY_SIZED
к ssSetNum
макрос. Если S-функция задерживает определение длины векторов работы в X
РаботаmdlInitializeSizes
, это должно обеспечить mdlSetWorkWidths
метод, чтобы настроить векторы работы.
Если S-функция использует mdlSetWorkWidths
, все работают, векторы, используемые в S-функции, должны быть установлены в DYNAMICALLY_SIZED
в mdlInitializeSizes
, даже если точное значение известно перед mdlInitializeSizes
называется. Размеры, которые будут использоваться S-функцией, чем заданный в mdlSetWorkWidths
.
Для примера смотрите sfun_dynsize.c
.
В mdlStart
, присвойте значения векторам работы, которые инициализируются только в начале симуляции. Используйте ssGet
макрос, чтобы получить указатель на каждого работает вектор и использует указатель, чтобы инициализировать значения вектора работы. В качестве альтернативы используйте X
РаботаssGet
присваивать значения конкретным элементам вектора работы.X
WorkValues
Механизм Simulink вызывает mdlStart
метод однажды в начале симуляции. Прежде, чем вызвать этот метод, механизм выделяет память для векторов работы. Не используйте mdlStart
метод для данных, которые должны быть повторно инициализированы в течение симуляции, например, данные, которые должны быть повторно инициализированы, когда активированная подсистема, содержащая S-функцию, включена.
В mdlInitializeConditions
, инициализируйте значения любого, работают векторы, которые могут должны быть быть повторно инициализированы в определенные моменты в симуляции. Механизм выполняет mdlInitializeConditions
в начале симуляции и любое время повторно включена активированная подсистема, содержащая S-функцию.
В mdlOutputs
, mdlUpdate
, и т.д. используйте ssGet
макрос, чтобы получить указатель на вектор работы и использовать указатель, чтобы получить доступ или обновить значения вектора работы.X
Работа
Запишите mdlRTW
метод, чтобы позволить Компилятору выходного языка (TLC) получать доступ к вектору работы. Этот шаг не необходим, если S-функция использует векторы DWork. Для получения информации о записи данных о параметре в mdlRTW
метод, смотрите ssWriteRTWParamSettings
. Для получения дополнительной информации о генерации кода с помощью mdlRTW
метод, смотрите Запись Полностью Встроенные S-функции с mdlRTW Стандартной программой (Simulink Coder).
Макрос | Описание |
---|---|
ssSetNumRWork | Задайте ширину действительного вектора работы. |
ssGetNumRWork | Запросите ширину действительного вектора работы. |
ssSetNumIWork | Задайте ширину целочисленного вектора работы. |
ssGetNumIWork | Запросите ширину целочисленного вектора работы. |
ssSetNumPWork | Укажите, что ширина указателя работает вектор. |
ssGetNumPWork | Запрос ширина указателя работает вектор. |
ssSetNumModes | Укажите, что ширина режима работает вектор. |
ssGetNumModes | Запрос ширина режима работает вектор. |
ssGetIWork | Получите указатель на целочисленный вектор работы. |
ssGetIWorkValue | Получите элемент целочисленного вектора работы. |
ssGetModeVector | Доберитесь указатель на режим работают вектор. |
ssGetModeVectorValue | Доберитесь элемент режима работают вектор. |
ssGetPWork | Доберитесь указатель на указатель работают вектор. |
ssGetPworkValue | Доберитесь один элемент от указателя работают вектор. |
ssGetRWork | Получите указатель на вектор работы с плавающей точкой. |
ssGetRWorkValue | Получите элемент вектора работы с плавающей точкой. |
ssSetIWorkValue | Установите значение одного элемента целочисленного вектора работы. |
ssSetModeVectorValue | Установите значение одного элемента режима, работают вектор. |
ssSetPWorkValue | Установите значение одного элемента указателя, работают вектор. |
ssSetRWorkValue | Установите значение одного элемента вектора работы с плавающей точкой. |
Следующие разделы обеспечивают примеры четырех типов элементарных векторов работы.
Этот пример открывает файл и хранит FILE
указатель в указателе работает вектор.
Следующий оператор, включенный в mdlInitializeSizes
функционируйте, указывает, что указатель работает, вектор должен содержать один элемент.
ssSetNumPWork(S, 1) /* pointer-work vector */
Следующее использование кода указатель работает вектор, чтобы сохранить FILE
указатель, возвращенный в стандартный ввод-вывод, функционирует fopen
.
#define MDL_START /* Change to #undef to remove function. */ #if defined(MDL_START) static void mdlStart(real_T *x0, SimStruct *S) { FILE *fPtr; void **PWork = ssGetPWork(S); fPtr = fopen("file.data", "r"); PWork[0] = fPtr; } #endif /* MDL_START */
Следующий код получает FILE
указатель от указателя работает вектор, и передает его fclose
для того, чтобы закрыть файл.
static void mdlTerminate(SimStruct *S) { if (ssGetPWork(S) != NULL) { FILE *fPtr; fPtr = (FILE *) ssGetPWorkValue(S,0); if (fPtr != NULL) { fclose(fPtr); } ssSetPWorkValue(S,0,NULL); } }
Несмотря на то, что указатели механизма Simulink, освобождающие вектор PWork, mdlTerminate
метод должен всегда освобождать память, сохраненную в векторе PWork.
S-функция stvctf.c
использование RWork и векторы IWork, чтобы смоделировать изменяющуюся во времени непрерывную передаточную функцию. Для описания этой S-функции смотрите Разрывы в качестве примера в Непрерывных состояниях.
Следующие реализации в качестве примера блок switch с помощью режима работают вектор. mdlInitializeSizes
метод конфигурирует два входных порта с прямым сквозным соединением и одним выходным портом. Элемент вектора режима указывает, распространен ли сигнал от первого или второго входного порта к выходу. S-функция использует один S-параметр-функции и соответствующий параметр периода выполнения, чтобы сохранить значение режима и позволить переключателю быть переключенным в процессе моделирования.
static void mdlInitializeSizes(SimStruct *S) { /* Initialize one S-function parameter to toggle the mode value */ ssSetNumSFcnParams(S, 1); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { /* Return if number of expected != number of actual parameters */ return; } { int iParam = 0; int nParam = ssGetNumSFcnParams(S); for ( iParam = 0; iParam < nParam; iParam++ ) { ssSetSFcnParamTunable( S, iParam, SS_PRM_TUNABLE ); } } /* Initialize two input ports with direct feedthrough */ if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortWidth(S, 1, 1); ssSetInputPortDataType( S, 0, SS_DOUBLE); ssSetInputPortDataType( S, 1, SS_DOUBLE); ssSetInputPortDirectFeedThrough( S, 0, 1); ssSetInputPortDirectFeedThrough( S, 1, 1); /* Initialize one output port */ if (!ssSetNumOutputPorts(S, 1)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortDataType( S, 0, SS_DOUBLE); /* Initialize one element in the mode vector */ ssSetNumSampleTimes(S, 1); ssSetNumModes(S,1); ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE | SS_OPTION_USE_TLC_WITH_ACCELERATOR | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | SS_OPTION_NONVOLATILE); }
mdlInitializeConditions
метод инициализирует значение вектора режима с помощью текущего значения диалогового параметра S-функции.
#define MDL_INITIALIZE_CONDITIONS /* Function: mdlInitializeConditions ============================= * Abstract: * Initialize the mode vector value. */ static void mdlInitializeConditions(SimStruct *S) { int_T *mv = ssGetModeVector(S); real_T param = mxGetScalar(ssGetSFcnParam(S,0)); mv[0] = (int_T)param; }
mdlProcessParameters
и mdlSetWorkWidths
методы инициализируют и обновляют параметр периода выполнения. Когда симуляция запускается, изменения в диалоговом параметре S-функции сопоставлены с параметром периода выполнения.
/* Function: mdlSetWorkWidths ============================================= * Abstract: * Sets the number of runtime parameters. */ #define MDL_SET_WORK_WIDTHS static void mdlSetWorkWidths(SimStruct *S) { ssSetNumRunTimeParams(S,1); ssRegDlgParamAsRunTimeParam(S,0,0,"P1",SS_INT16); } /* Function: mdlProcessParameters =========================================== * Abstract: * Update run-time parameters. */ #define MDL_PROCESS_PARAMETERS static void mdlProcessParameters(SimStruct *S) { ssUpdateDlgParamAsRunTimeParam(S,0); }
mdlOutputs
метод обновляет значение вектора режима с новым значением параметра периода выполнения на каждом главном временном шаге. Это затем использует значение вектора режима, чтобы определить который входной сигнал передать до выхода.
static void mdlOutputs(SimStruct *S, int_T tid) { InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); InputRealPtrsType u2Ptrs = ssGetInputPortRealSignalPtrs(S,1); real_T *y = ssGetOutputPortSignal(S,0); int_T *mode = ssGetModeVector(S); real_T param = mxGetScalar(ssGetSFcnParam(S,0)); if (ssIsMajorTimeStep(S)) { mode[0] = (int_T)param; } if (!mode[0]) { /* first input */ y[0] = (*uPtrs[0]); } if (mode[0]) { /* second input */ y[0] = (*u2Ptrs[0]); } }