Следующие шаги показывают, как инициализировать и использовать векторы DWork в S-функции MEX C. Для полного списка SimStruct
макросы, имеющие отношение к векторам DWork, см. Вектор DWork C Макросы MEX.
В mdlInitializeSizes
, задайте количество векторов DWork с помощью ssSetNumDWork
макрос. Например, чтобы указать, что S-функция содержит два вектора DWork, используйте команду
ssSetNumDWork(S, 2);
Несмотря на то, что mdlInitializeSizes
метод говорит механизм Simulink®, сколько векторов DWork S-функция будет использовать, механизм не выделяет память для векторов DWork в это время.
S-функция может задержать определение количества векторов DWork, пока вся информация о S-входных-параметрах-функции не доступна путем передачи значения DYNAMICALLY_SIZED
к ssSetNumDWork
макрос. Если S-функция задерживает определение количества векторов DWork в mdlInitializeSizes
, это должно обеспечить mdlSetWorkWidths
метод, чтобы настроить векторы DWork.
Если S-функция не обеспечивает mdlSetWorkWidths
метод, mdlInitializeSizes
метод устанавливает любые применимые атрибуты для каждого вектора DWork. Например, следующие линии инициализируют ширины и типы данных векторов DWork, инициализированных на предыдущем шаге.
ssSetDWorkWidth(S, 0, 2); ssSetDWorkWidth(S, 1, 1); ssSetDWorkDataType(S, 0, SS_DOUBLE); ssSetDWorkDataType(S, 1, SS_BOOLEAN);
В следующей таблице перечислены атрибуты, которые вы можете установить для вектора DWork и показываете пример макроса, который устанавливает ее. Смотрите ssSetDWorkRTWStorageClass
для списка поддерживаемых классов памяти.
Атрибут | Макрос |
---|---|
Тип данных |
|
Размер |
|
Имя |
|
Тип использования |
|
Числовой тип, или действительный или комплексный |
|
Идентификатор Simulink Coder™ |
|
Класс памяти Simulink Coder |
|
Simulink Coder C вводит спецификатор |
|
В mdlStart
, инициализируйте значения любых векторов DWork, которые должны быть установлены только в начале симуляции. Используйте ssGetDWork
макрос, чтобы получить указатель на каждый вектор DWork и инициализировать значения. Например, следующий mdlStart
метод инициализирует первый вектор DWork.
static void mdlStart(SimStruct *S) { real_T *x = (real_T*) ssGetDWork(S,0); /* Initialize the first DWork vector */ x[0] = 0; x[1] = 2; }
Механизм Simulink выделяет память для вектора DWork прежде, чем вызвать mdlStart
метод. Поскольку mdlStart
метод называется только однажды в начале симуляции, не используйте его в данных или состояниях, которые должны быть повторно инициализированы, например, при перевключении отключенной подсистемы, содержащей S-функцию.
В mdlInitializeConditions
, инициализируйте значения любых векторов DWork, которые должны быть повторно инициализированы в определенные моменты в симуляции. Механизм выполняет mdlInitializeConditions
в начале симуляции и любое время повторно включена активированная подсистема, содержащая S-функцию. Смотрите mdlStart
пример на предыдущем шаге для команд раньше инициализировал векторные значения DWork.
В mdlOutputs
, mdlUpdate
, и т.д. используйте ssGetDWork
макрос, чтобы получить указатель на вектор DWork и использовать или обновить векторные значения DWork. Например, для вектора DWork, хранящего два дискретных состояния, следующий mdlOutputs
и mdlUpdate
методы вычисляют выход и обновляют значения дискретного состояния.
S-функция ранее задала U(element)
как (*uPtrs[element])
A
B
C
, и D
как матрицы пространства состояний для дискретной системы в пространстве состояний.
/* Function: mdlOutputs ============================================== * Abstract: * y = Cx + Du */ static void mdlOutputs(SimStruct *S, int_T tid) { if( ssGetDWorkUsageType(S, 0) == SS_DWORK_USED_AS_DSTATE) { real_T *y = ssGetOutputPortRealSignal(S,0); real_T *x = (real_T*) ssGetDWork(S, 0); InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); UNUSED_ARG(tid); /* not used in single tasking mode */ /* y=Cx+Du */ y[0]=C[0][0]*x[0]+C[0][1]*x[1]+D[0][0]*U(0)+D[0][1]*U(1); y[1]=C[1][0]*x[0]+C[1][1]*x[1]+D[1][0]*U(0)+D[1][1]*U(1); } } #define MDL_UPDATE /* Function: mdlUpdate =============================================== * Abstract: * xdot = Ax + Bu */ static void mdlUpdate(SimStruct *S, int_T tid) { real_T tempX[2] = {0.0, 0.0}; real_T *x = (real_T*) ssGetDWork(S, 0); InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); UNUSED_ARG(tid); /* not used in single tasking mode */ /* xdot=Ax+Bu */ tempX[0]=A[0][0]*x[0]+A[0][1]*x[1]+B[0][0]*U(0)+B[0][1]*U(1); tempX[1]=A[1][0]*x[0]+A[1][1]*x[1]+B[1][0]*U(0)+B[1][1]*U(1); x[0]=tempX[0]; x[1]=tempX[1]; }
Вы не должны включать код в mdlTerminate
метод, чтобы освободить память раньше хранил вектор DWork. Точно так же, если вы генерируете встроенный код для S-функции, вы не должны писать mdlRTW
метод, чтобы получить доступ к вектору DWork в файле TLC. Программное обеспечение Simulink обрабатывает эти аспекты вектора DWork для вас.
В следующей таблице перечислены макросы MEX C, имеющие отношение к векторам DWork.
Макрос | Описание |
---|---|
ssSetNumDWork | Задайте количество векторов DWork. |
ssGetNumDWork | Запросите количество векторов DWork. |
ssGetDWork | Получите указатель на определенный вектор DWork. |
ssGetDWorkComplexSignal | Определите, является ли определенный вектор DWork действительным или комплексным. |
ssGetDWorkDataType | Получите тип данных вектора DWork. |
ssGetDWorkName | Получите имя вектора DWork. |
ssGetDWorkRTWIdentifier | Используйте идентификатор, чтобы объявить вектор DWork в сгенерированном коде. |
ssGetDWorkRTWIdentifierMustResolveToSignalObject | Укажите, должен ли вектор DWork решить к Simulink.Signal объект в рабочей области MATLAB®. |
ssGetDWorkRTWStorageClass | Получите класс памяти вектора DWork. |
ssGetDWorkRTWTypeQualifier | Доберитесь спецификатор типа C раньше объявлял вектор DWork в сгенерированном коде. |
ssGetDWorkUsageType | Определите, как вектор DWork используется в S-функции. |
ssGetDWorkUsedAsDState | Определите, хранит ли вектор DWork дискретные состояния. |
ssGetDWorkWidth | Получите размер вектора DWork. |
ssSetDWorkComplexSignal | Задайте, являются ли элементы вектора DWork действительными или комплексными. |
ssSetDWorkDataType | Задайте тип данных вектора DWork. |
ssSetDWorkName | Задайте имя вектора DWork. |
ssSetDWorkRTWIdentifier | Укажите, что идентификатор раньше объявлял вектор DWork в сгенерированном коде. |
ssSetDWorkRTWIdentifierMustResolveToSignalObject | Задайте, должен ли вектор DWork решить к Simulink.Signal объект. |
ssSetDWorkRTWStorageClass | Задайте класс памяти для вектора DWork. |
ssSetDWorkRTWTypeQualifier | Укажите, что спецификатор типа C раньше объявлял вектор DWork в сгенерированном коде. |
ssSetDWorkUsageType | Задайте, как вектор DWork используется в S-функции. |
ssSetDWorkUsedAsDState | Укажите, что вектор DWork хранит значения дискретного состояния. |
ssSetDWorkWidth | Задайте ширину вектора DWork. |
Можно использовать векторы DWork, чтобы связаться с унаследованным кодом. Если у вас есть существующий код, который выделяет структуры данных в памяти, сохраните указатель на те структуры данных в векторе DWork. Ваша S-функция может затем связаться с унаследованным кодом через указатель. В качестве альтернативы для простоты в подготовке вашей S-функции, можно использовать указатель, работают вектор, чтобы сохранить указатель. Смотрите, что Элементарные Векторы работы для описания указателя работают векторы.
Можно также использовать векторы DWork, чтобы сохранить состояние унаследованного кода. Файл шаблона sfuntmpl_gate_fortran.c
показывает, как использовать векторы DWork, чтобы взаимодействовать с устаревшим кодом Фортран. Legacy Code Tool использует векторы DWork, чтобы обеспечить состояния устаревшего кода C or C++, включенного через инструмент. Смотрите Интегрируют Функции C Используя Legacy Code Tool для получения дополнительной информации о Legacy Code Tool.