Следующие шаги показывают, как инициализировать и использовать векторы DWork в S-функции MEX на C. Полный список SimStruct
макросы, относящиеся к векторам DWork, см. DWork Vector C MEX Macros.
В 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. Точно так же, если вы генерируете inlined код для S-функции, вы не должны писать mdlRTW
метод для доступа к вектору DWork в файле TLC. Программа Simulink обрабатывает эти аспекты вектора DWork для вас.
В следующей таблице перечислены макросы C MEX, относящиеся к векторам 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-функции можно использовать рабочий вектор указателя для хранения указателя. Описание рабочих векторов указателя смотрите в Elementary Работы Vectors.
Можно также использовать векторы DWork для хранения состояния унаследованного кода. Файл шаблона sfuntmpl_gate_fortran.c
показывает, как использовать векторы DWork для взаимодействия с устаревшим код Фортраном. Legacy Code Tool использует векторы DWork для поддержания состояний устаревших кодов C or C++, встроенных через инструмент. Смотрите Интегрировать функции C с помощью Legacy Code Tool для получения дополнительной информации о Legacy Code Tool.