Следующие шаги показывают, как инициализировать и использовать векторы 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 или Кода С++, включенного через инструмент. Смотрите Интегрируют Функции C Используя Legacy Code Tool для получения дополнительной информации о Legacy Code Tool.