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

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

Следующие шаги показывают, как инициализировать и использовать векторы DWork в S-функции MEX на C. Полный список 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);
    Идентификатор Simulink Coder™ssSetDWorkRTWIdentifier(S, 0, «Усиление»);
    Класс памяти Simulink CoderssSetDWorkRTWStorageClass(S, 0, 2);
    Классификатор типа Simulink Coder CssSetDWorkRTWTypeQualifier(S, 0, «летучий»);
  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. Точно так же, если вы генерируете inlined код для S-функции, вы не должны писать mdlRTW метод для доступа к вектору DWork в файле TLC. Программа Simulink обрабатывает эти аспекты вектора DWork для вас.

Макросы MEX вектора DWork C

В следующей таблице перечислены макросы 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-функции можно использовать рабочий вектор указателя для хранения указателя. Описание рабочих векторов указателя смотрите в Elementary Работы Vectors.

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