exponenta event banner

Использование векторов DWork

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

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

  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);
    Идентификатор Coder™ SimulinkssSetDWorkRTWIdentifier(S, 0, "Gain");
    Класс хранения Simulink CoderssSetDWorkRTWStorageClass(S, 0, 2);
    Квалификатор типа Simulink Coder CssSetDWorkRTWTypeQualifier(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 Vector C MEX

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

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