Как использовать векторы DWork

Используя векторы DWork в S-функциях MEX C

Следующие шаги показывают, как инициализировать и использовать векторы DWork в S-функции MEX C. Для полного списка SimStruct макросы, имеющие отношение к векторам DWork, см. Вектор DWork C Макросы MEX.

  1. \in mdlInitializeSizes, задайте количество векторов DWork с помощью ssSetNumDWork макрос. Например, чтобы указать, что S-функция содержит два вектора DWork, используйте команду

    ssSetNumDWork(S, 2);

    Несмотря на то, что mdlInitializeSizes метод говорит Simulink® механизм, сколько векторы DWork S-функция будут использовать, механизм, не выделяет память для векторов DWork в это время.

    S-функция может задержать определение количества векторов DWork, пока вся информация о S-входных-параметрах-функции не доступна путем передачи значения DYNAMICALLY_SIZED к ssSetNumDWork макрос. Если S-функция задерживает определение количества векторов DWork в mdlInitializeSizes, это должно обеспечить a mdlSetWorkWidths метод, чтобы настроить векторы DWork.

  2. Если 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 для списка поддерживаемых классов памяти.

    АтрибутМакрос
    Тип данныхssSetDWorkDataType(S, 0, SS_DOUBLE);
    РазмерssSetDWorkWidth(S, 0, 2);
    ИмяssSetDWorkName(S, 0, "sfcnState");
    Тип использованияssSetDWorkUsageType(S, 0, SS_DWORK_USED_AS_DSTATE);
    Числовой тип, или действительный или комплексныйssSetDWorkComplexSignal(S, 0, COMPLEX_NO);
    Идентификатор Simulink Coder™ssSetDWorkRTWIdentifier(S, 0, "Усиление");
    Класс памяти Simulink CoderssSetDWorkRTWStorageClass(S, 0, 2);
    Simulink Coder C вводит спецификаторssSetDWorkRTWTypeQualifier(S, 0, "энергозависимый");
  3. \in 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-функцию.

  4. \in mdlInitializeConditions, инициализируйте значения любых векторов DWork, которые должны быть повторно инициализированы в определенные моменты в симуляции. Механизм выполняет mdlInitializeConditions в начале симуляции и любое время повторно включена активированная подсистема, содержащая S-функцию. Смотрите mdlStart пример на предыдущем шаге для команд раньше инициализировал векторные значения DWork.

  5. \in mdlOutputs, mdlUpdate, и т.д. используйте ssGetDWork макрос, чтобы получить указатель на вектор DWork и использовать или обновить векторные значения DWork. Например, для вектора DWork, хранящего два дискретных состояния, следующий mdlOutputs и mdlUpdate методы вычисляют выход и обновляют значения дискретного состояния.

    S-функция ранее задала U(element) как (*uPtrs[element])ABC, и 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 для вас.

Вектор DWork C макросы MEX

В следующей таблице перечислены макросы 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, чтобы связаться с унаследованным кодом. Если у вас есть существующий код, который выделяет структуры данных в памяти, сохраните указатель на те структуры данных в векторе DWork. Ваша S-функция может затем связаться с унаследованным кодом через указатель. В качестве альтернативы для простоты в подготовке вашей S-функции, можно использовать указатель, работают вектор, чтобы сохранить указатель. Смотрите, что Элементарные Векторы работы для описания указателя работают векторы.

Можно также использовать векторы DWork, чтобы сохранить состояние унаследованного кода. Файл шаблона sfuntmpl_gate_fortran.c показывает, как использовать векторы DWork, чтобы взаимодействовать с устаревшим кодом Фортран. Legacy Code Tool использует векторы DWork, чтобы обеспечить состояния устаревшего кода C or C++, включенного через инструмент. Смотрите Интегрируют Функции C Используя Legacy Code Tool для получения дополнительной информации о Legacy Code Tool.