В дополнение к векторам 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
задайте размер векторов работы с помощью макроса
, например:ssSetNumXWork
ssSetNumPWork(2);
Этот макрос указывает, сколько элементов вектор работы содержит, однако, механизм Simulink не выделяет память в это время.
S-функция может задержать определение длины векторов работы, пока вся информация о S-входных-параметрах-функции не доступна путем передачи значения DYNAMICALLY_SIZED
макросу
. Если S-функция задерживает определение длины векторов работы в ssSetNumXWork
mdlInitializeSizes
, это должно предоставить метод mdlSetWorkWidths
, чтобы настроить векторы работы.
Если S-функция использует mdlSetWorkWidths
, все работают, векторы, используемые в S-функции, должны быть установлены в DYNAMICALLY_SIZED
в mdlInitializeSizes
, даже если точное значение известно, прежде чем mdlInitializeSizes
называется. Размеры, которые будут использоваться S-функцией, чем заданный в mdlSetWorkWidths
.
Для примера смотрите sfun_dynsize.c
c.
В mdlStart
, значениях присвоения к векторам работы, которые инициализируются только в начале моделирования. Используйте макрос
, чтобы получить указатель на каждого, работают вектор и используют указатель, чтобы инициализировать значения вектора работы. Также используйте ssGetXWork
, чтобы присвоить значения конкретным элементам вектора работы.ssGetXWorkValues
Механизм Simulink вызывает метод mdlStart
однажды в начале моделирования. Прежде, чем вызвать этот метод, механизм выделяет память для векторов работы. Не используйте метод mdlStart
для данных, который должен быть повторно инициализирован в течение моделирования, например, данные, который должен быть повторно инициализирован, когда активированная подсистема, содержащая S-функцию, включена.
В mdlInitializeConditions
инициализируйте значения любого, работают векторы, которые могут должны быть быть повторно инициализированы в определенные моменты в моделировании. Механизм выполняет mdlInitializeConditions
в начале моделирования и любое время, которое повторно включена активированная подсистема, содержащая S-функцию.
В mdlOutputs
mdlUpdate
, и т.д., использует макрос
, чтобы получить указатель на вектор работы и использовать указатель, чтобы получить доступ или обновить значения вектора работы.ssGetXWork
Запишите метод 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]); } }