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

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

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

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

    ssSetNumDWork(S, 2);

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

    S-функция может задержать определение количества векторов DWork, пока вся информация о S-входных-параметрах-функции не доступна путем передачи значения DYNAMICALLY_SIZED макросу ssSetNumDWork. Если S-функция задерживает определение количества векторов DWork в mdlInitializeSizes, это должно предоставить метод 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, "Gain");
    Класс памяти Simulink CoderssSetDWorkRTWStorageClass(S, 0, 2);
    Simulink Coder C вводит спецификаторssSetDWorkRTWTypeQualifier(S, 0, "volatile");
  3. В 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. В mdlInitializeConditions инициализируйте значения любых векторов DWork, которые должны быть повторно инициализированы в определенные моменты в симуляции. Механизм выполняет mdlInitializeConditions в начале симуляции и любое время, которое повторно включена активированная подсистема, содержащая S-функцию. Смотрите, что пример mdlStart на предыдущем шаге для команд раньше инициализировал векторные значения DWork.

  5. В 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 для вас.

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