Элементарные векторы работы

Описание элементарного вектора работы

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

  • Векторы iWork хранят целочисленные данные.

  • Модель векторов режима обнуляет пересечения или другие функции, которые требуют одного вектора режима.

  • Векторы PWork хранят указатели на структуры данных, такие как те, которые соединяют интерфейсом с S-функцией к унаследованному коду, другому программному обеспечению или аппаратному приложению.

  • Векторы RWork хранят (действительные) данные с плавающей точкой.

Отношение к векторам DWork

Следующая таблица сравнивает каждый тип вектора работы к вектору DWork.

Тип вектора работыСравнение с вектором DWorkКак создать эквивалентный вектор DWork
IWorkВекторы iWork не могут быть настроены в сгенерированном коде. Кроме того, вам разрешают только один вектор IWork.
ssSetNumDWork(S,1);
ssSetDWorkDataType(S, 0, SS_INT8);
РежимВекторы режима требуют большей памяти, чем векторы DWork, поскольку вектор режима всегда хранится integer тип данных. Кроме того, вам разрешают только один вектор Режима.
ssSetNumDWork(S,1);
ssSetDWorkUsageType(S, 0, 
   sSS_DWORK_USED_AS_MODE);
ssSetDWorkDataType(S, 0, SS_INT8);
PWorkВ отличие от векторов DWork, векторы PWork нельзя назвать в сгенерированном коде. Кроме того, вам разрешают только один вектор PWork.
ssSetNumDWork(S,1);
ssSetDWorkDataType(S, 0, SS_POINTER);
Вектор DWork затем хранит указатель.
RWorkВекторы RWork не могут быть настроены в сгенерированном коде. Кроме того, вам разрешают только один вектор RWork.
ssSetNumDWork(S,1);
ssSetDWorkDataType(S, 0, SS_DOUBLE);

Используя элементарные векторы работы

Процесс для использования элементарных векторов работы похож на это для векторов DWork (см. Используя Векторы DWork в S-функциях MEX C.) Элементарные векторы работы имеют меньше свойств, таким образом, процесс инициализации более прост. Однако, если необходимо сгенерировать код для S-функции, S-функция становится более включенной чем тогда, когда с помощью векторов DWork.

Следующие шаги показывают, как настроить и использовать элементарные векторы работы. Смотрите Макросы Вектора Дополнительной работы для списка макросов, связанных с каждым шагом в следующем процессе.

  1. В mdlInitializeSizes, задайте размер векторов работы с помощью ssSetNumXРабота макрос, например:

    ssSetNumPWork(S, 2);

    Этот макрос указывает, сколько элементов вектор работы содержит, однако, механизм Simulink не выделяет память в это время.

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

    Примечание

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

    Для примера смотрите sfun_dynsize.c.

  2. В mdlStart, присвойте значения векторам работы, которые инициализируются только в начале симуляции. Используйте ssGetXРабота макрос, чтобы получить указатель на каждого работает вектор и использует указатель, чтобы инициализировать значения вектора работы. В качестве альтернативы используйте ssGetXWorkValues присваивать значения конкретным элементам вектора работы.

    Механизм Simulink вызывает mdlStart метод однажды в начале симуляции. Прежде, чем вызвать этот метод, механизм выделяет память для векторов работы. Не используйте mdlStart метод для данных, которые должны быть повторно инициализированы в течение симуляции, например, данные, которые должны быть повторно инициализированы, когда активированная подсистема, содержащая S-функцию, включена.

  3. В mdlInitializeConditions, инициализируйте значения любого, работают векторы, которые могут должны быть быть повторно инициализированы в определенные моменты в симуляции. Механизм выполняет mdlInitializeConditions в начале симуляции и любое время повторно включена активированная подсистема, содержащая S-функцию.

  4. В mdlOutputs, mdlUpdate, и т.д. используйте ssGetXРабота макрос, чтобы получить указатель на вектор работы и использовать указатель, чтобы получить доступ или обновить значения вектора работы.

  5. Запишите mdlRTW метод, чтобы позволить Компилятору выходного языка (TLC) получать доступ к вектору работы. Этот шаг не необходим, если S-функция использует векторы DWork. Для получения информации о записи данных о параметре в mdlRTW метод, смотрите ssWriteRTWParamSettings. Для получения дополнительной информации о генерации кода с помощью mdlRTW метод, смотрите Запись Полностью Встроенные S-функции с mdlRTW Стандартной программой (Simulink Coder).

Макросы вектора дополнительной работы

МакросОписание
ssSetNumRWorkЗадайте ширину действительного вектора работы.
ssGetNumRWorkЗапросите ширину действительного вектора работы.
ssSetNumIWorkЗадайте ширину целочисленного вектора работы.
ssGetNumIWorkЗапросите ширину целочисленного вектора работы.
ssSetNumPWorkУкажите, что ширина указателя работает вектор.
ssGetNumPWorkЗапрос ширина указателя работает вектор.
ssSetNumModesУкажите, что ширина режима работает вектор.
ssGetNumModesЗапрос ширина режима работает вектор.
ssGetIWorkПолучите указатель на целочисленный вектор работы.
ssGetIWorkValueПолучите элемент целочисленного вектора работы.
ssGetModeVectorДоберитесь указатель на режим работают вектор.
ssGetModeVectorValueДоберитесь элемент режима работают вектор.
ssGetPWorkДоберитесь указатель на указатель работают вектор.
ssGetPworkValueДоберитесь один элемент от указателя работают вектор.
ssGetRWorkПолучите указатель на вектор работы с плавающей точкой.
ssGetRWorkValueПолучите элемент вектора работы с плавающей точкой.
ssSetIWorkValueУстановите значение одного элемента целочисленного вектора работы.
ssSetModeVectorValueУстановите значение одного элемента режима, работают вектор.
ssSetPWorkValueУстановите значение одного элемента указателя, работают вектор.
ssSetRWorkValueУстановите значение одного элемента вектора работы с плавающей точкой.

Элементарные примеры вектора работы

Следующие разделы обеспечивают примеры четырех типов элементарных векторов работы.

Вектор работы указателя

Этот пример открывает файл и хранит FILE указатель в указателе работает вектор.

Следующий оператор, включенный в mdlInitializeSizes функционируйте, указывает, что указатель работает, вектор должен содержать один элемент.

ssSetNumPWork(S, 1)   /* pointer-work vector */

Следующее использование кода указатель работает вектор, чтобы сохранить FILE указатель, возвращенный в стандартный ввод-вывод, функционирует fopen.

#define MDL_START  /* Change to #undef to remove function. */
#if defined(MDL_START)
static void mdlStart(real_T *x0, SimStruct *S)
{
  FILE *fPtr;
  void **PWork = ssGetPWork(S);
  fPtr = fopen("file.data", "r");
  PWork[0] = fPtr;
}
#endif /*  MDL_START */

Следующий код получает FILE указатель от указателя работает вектор, и передает его fclose для того, чтобы закрыть файл.

static void mdlTerminate(SimStruct *S)
{
  if (ssGetPWork(S) != NULL) {
    FILE *fPtr;
    fPtr = (FILE *) ssGetPWorkValue(S,0);
    if (fPtr != NULL) {
      fclose(fPtr);
    }
    ssSetPWorkValue(S,0,NULL);
  }
}

Примечание

Несмотря на то, что указатели механизма Simulink, освобождающие вектор PWork, mdlTerminate метод должен всегда освобождать память, сохраненную в векторе PWork.

Действительные и целочисленные векторы работы

S-функция stvctf.c использование RWork и векторы IWork, чтобы смоделировать изменяющуюся во времени непрерывную передаточную функцию. Для описания этой S-функции смотрите Разрывы в качестве примера в Непрерывных состояниях.

Вектор режима

Следующие реализации в качестве примера блок switch с помощью режима работают вектор. mdlInitializeSizes метод конфигурирует два входных порта с прямым сквозным соединением и одним выходным портом. Элемент вектора режима указывает, распространен ли сигнал от первого или второго входного порта к выходу. S-функция использует один S-параметр-функции и соответствующий параметр периода выполнения, чтобы сохранить значение режима и позволить переключателю быть переключенным в процессе моделирования.

static void mdlInitializeSizes(SimStruct *S)
{
    /* Initialize one S-function parameter to toggle the mode value */
    ssSetNumSFcnParams(S, 1);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        /* Return if number of expected != number of actual parameters */
        return;
    }

    {
        int iParam = 0;
        int nParam = ssGetNumSFcnParams(S);

        for ( iParam = 0; iParam < nParam; iParam++ )
        {
            ssSetSFcnParamTunable( S, iParam, SS_PRM_TUNABLE );
        }
    }
    /* Initialize two input ports with direct feedthrough */
    if (!ssSetNumInputPorts(S, 2)) return;
    ssSetInputPortWidth(S, 0, 1);
    ssSetInputPortWidth(S, 1, 1);
    ssSetInputPortDataType(  S, 0, SS_DOUBLE);
    ssSetInputPortDataType(  S, 1, SS_DOUBLE);
    ssSetInputPortDirectFeedThrough(  S, 0, 1);
    ssSetInputPortDirectFeedThrough(  S, 1, 1);

    /* Initialize one output port */
    if (!ssSetNumOutputPorts(S, 1)) return;
    ssSetOutputPortWidth(S, 0, 1);
    ssSetOutputPortDataType(  S, 0, SS_DOUBLE);

    /* Initialize one element in the mode vector */
    ssSetNumSampleTimes(S, 1);
    ssSetNumModes(S,1);
    
    ssSetOptions(S,
                 SS_OPTION_WORKS_WITH_CODE_REUSE |
                 SS_OPTION_USE_TLC_WITH_ACCELERATOR |
                 SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME |
                 SS_OPTION_NONVOLATILE);
}

mdlInitializeConditions метод инициализирует значение вектора режима с помощью текущего значения диалогового параметра S-функции.

#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions =============================
 * Abstract:
 *    Initialize the mode vector value.
 */
static void mdlInitializeConditions(SimStruct *S)
{
    int_T *mv = ssGetModeVector(S);
    real_T param = mxGetScalar(ssGetSFcnParam(S,0));
    mv[0] = (int_T)param;
}

mdlProcessParameters и mdlSetWorkWidths методы инициализируют и обновляют параметр периода выполнения. Когда симуляция запускается, изменения в диалоговом параметре S-функции сопоставлены с параметром периода выполнения.

/* Function: mdlSetWorkWidths =============================================
 * Abstract:
 *    Sets the number of runtime parameters.
 */
#define MDL_SET_WORK_WIDTHS
static void mdlSetWorkWidths(SimStruct *S) {
    ssSetNumRunTimeParams(S,1);
    ssRegDlgParamAsRunTimeParam(S,0,0,"P1",SS_INT16);
}

/* Function: mdlProcessParameters ===========================================
 * Abstract:
 *      Update run-time parameters.
 */
#define MDL_PROCESS_PARAMETERS
static void mdlProcessParameters(SimStruct *S)
{
    ssUpdateDlgParamAsRunTimeParam(S,0);
}

mdlOutputs метод обновляет значение вектора режима с новым значением параметра периода выполнения на каждом главном временном шаге. Это затем использует значение вектора режима, чтобы определить который входной сигнал передать до выхода.

static void mdlOutputs(SimStruct *S, int_T tid)
{
    InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
    InputRealPtrsType u2Ptrs = ssGetInputPortRealSignalPtrs(S,1);
    real_T    *y = ssGetOutputPortSignal(S,0);
    int_T  *mode = ssGetModeVector(S);
    real_T param = mxGetScalar(ssGetSFcnParam(S,0));
    
    if (ssIsMajorTimeStep(S)) {
        mode[0] =  (int_T)param;
    }

    if (!mode[0]) {
        /* first input */
        y[0] = (*uPtrs[0]);
    }
    if (mode[0]) {
        /* second input */
        y[0] = (*u2Ptrs[0]);
    }
}