exponenta event banner

Преобразовать Level-1 C MEX S-функции

Рекомендации по преобразованию Level-1 C MEX S-функций в Level-2

Level-2 S-функции были представлены в Simulink ® версии 2.2. Level-1 S-функции относятся к S-функциям, написанным для работы с Simulink версии 2.1 и предыдущих версий. Level-1 S-функции совместимы с Simulink версии 2.2 и последующих выпусков; их можно использовать в новых моделях без внесения изменений в код. Однако, чтобы воспользоваться преимуществами новых функций в S-функциях, Level-1 S-функции должны быть обновлены до Level-2 S-функций. Вот несколько рекомендаций:

  • Начните с просмотра simulink/src/sfunctmpl_doc.c. Этот файл шаблона S-функции кратко резюмирует Level-2 S-функции.

  • В верхней части файла S-функции добавьте следующее определение:

    #define S_FUNCTION_LEVEL 2
    
  • Обновить содержимое mdlInitializeSizes. В частности, добавьте следующую обработку ошибок для количества параметров S-функции:

    ssSetNumSFcnParams(S, NPARAMS); /*Number of expected parameters*/
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
    	/* Return if number of expected != number of actual parameters */
      	return;
    }
    Set up the inputs using: 
    if (!ssSetNumInputPorts(S, 1)) return; /*Number of input ports */
    ssSetInputPortWidth(S, 0, width);      /* Width of input 
                                              port one (index 0)*/ 
    ssSetInputPortDirectFeedThrough(S, 0, 1); /* Direct feedthrough
                                                 or port one */
    ssSetInputPortRequiredContiguous(S, 0);
    Set up the outputs using:
    if (!ssSetNumOutputPorts(S, 1)) return;
    ssSetOutputPortWidth(S, 0, width);     /* Width of output port
                                              one (index 0) */
    
  • Если S-функция имеет непустую mdlInitializeConditions, обновите его до следующей формы:

    #define MDL_INITIALIZE_CONDITIONS
    static void mdlInitializeConditions(SimStruct *S)
    {
    }
    

    В противном случае удалите функцию.

    • Доступ к непрерывным состояниям с помощью ssGetContStates. ssGetX макрос удален.

    • Доступ к дискретным состояниям с помощью ssGetRealDiscStates(S). ssGetX макрос удален.

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

  • mdlOutputs прототип изменен с

    static void mdlOutputs( real_T *y, const real_T *x, 
    	const real_T *u, SimStruct *S, int_T tid)
    

    кому

    static void mdlOutputs(SimStruct *S, int_T tid)
    

    С тех пор y, x, и u не передаются явно в Level-2 S-функции, необходимо использовать

    • ssGetInputPortSignal для доступа к входам

    • ssGetOutputPortSignal для доступа к выходам

    • ssGetContStates или ssGetRealDiscStates для доступа к состояниям

  • mdlUpdate прототип функции изменен с

    void mdlUpdate(real_T *x, real_T *u, Simstruct *S, int_T tid)
    

    кому

    void mdlUpdate(SimStruct *S, int_T tid)
    
  • Если S-функция имеет непустую mdlUpdate, обновите его до этой формы:

    #define MDL_UPDATE
    static void mdlUpdate(SimStruct *S, int_T tid)
    {
    }
    

    В противном случае удалите функцию.

  • Если S-функция имеет непустую mdlDerivatives, обновите его до этой формы:

    #define MDL_DERIVATIVES
    static void mdlDerivatives(SimStruct *S)
    {
    }
    

    В противном случае удалите функцию.

  • Заменить все устаревшие SimStruct макросы. Полный список устаревших макросов см. в разделе Устаревшие макросы.

  • Преобразовывая S-функции Уровня 1 в S-функции Уровня 2, Вы должны построить свои S-функции с полным (т.е. самый высокий) предупреждение уровней. Например, если имеется gcc в системе UNIX ® [1] используйте эти опции с mex утилита.

    mex CC=gcc CFLAGS=-Wall sfcn.c
    

    Если в вашей системе есть Lint, используйте этот код.

    lint -DMATLAB_MEX_FILE -I<matlabroot>/simulink/include 
        -Imatlabroot/extern/include sfcn.c 
    

    На ПК для использования самых высоких уровней предупреждения необходимо создать файл проекта в интегрированной среде разработки (IDE) для используемого компилятора. В файле проекта определите MATLAB_MEX_FILE и добавить

    matlabroot/simulink/include 
    matlabroot/extern/include 
    

    к контуру (не забудьте построить с выравниванием, равным 8).

Устаревшие макросы

Следующие макросы устарели. Замените каждый устаревший макрос макросом, указанным в следующей таблице.

Устаревший макросЗаменить на
ssGetU(S), ssGetUPtrs(S)ssGetInputPortSignalPtrs(S,port), ssGetInputPortSignal(S,port)
ssGetY(S)ssGetOutputPortRealSignal(S,port)
ssGetX(S)ssGetContStates(S), ssGetRealDiscStates(S)
ssGetStatus(S) Обычно не используется, но ssGetErrorStatus(S) доступен.
ssSetStatus(S,msg) ssSetErrorStatus(S,msg)
ssGetSizes(S) Конкретный вызов для требуемого товара (т. е. ssGetNumContStates(S))
ssGetMinStepSize(S)Больше не поддерживается
ssGetPresentTimeEvent(S,sti)ssGetTaskTime(S,sti)
ssGetSampleTimeEvent(S,sti)ssGetSampleTime(S,sti)
ssSetSampleTimeEvent(S,t)ssSetSampleTime(S,sti,t)
ssGetOffsetTimeEvent(S,sti)ssGetOffsetTime(S,sti)
ssSetOffsetTimeEvent(S,sti,t)ssSetOffsetTime(S,sti,t)
ssIsSampleHitEvent(S,sti,tid) ssIsSampleHit(S,sti,tid)
ssGetNumInputArgs(S) ssGetNumSFcnParams(S)
ssSetNumInputArgs(S, numInputArgs)ssSetNumSFcnParams(S,numInputArgs)
ssGetNumArgs(S)ssGetSFcnParamsCount(S)
ssGetArg(S,argNum)ssGetSFcnParam(S,argNum)
ssGetNumInputsssGetNumInputPorts(S) и ssGetInputPortWidth(S,port)
ssSetNumInputsssSetNumInputPorts(S,nInputPorts) и ssSetInputPortWidth(S,port,val)
ssGetNumOutputsssGetNumOutputPorts(S) и ssGetOutputPortWidth(S,port)
ssSetNumOutputsssSetNumOutputPorts(S,nOutputPorts) и ssSetOutputPortWidth(S,port,val)

См. также

| | |

Связанные темы


[1] UNIX является зарегистрированным товарным знаком Открытой группы в США и других странах.