matlab_23550/Inu/MCU.c

206 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
**************************************************************************
* @file MCU.c
* @brief Исходный код S-Function.
**************************************************************************
@details
Данный файл содержит функции S-Function, который вызывает MATLAB.
**************************************************************************
@note
Описание функций по большей части сгенерировано MATLAB'ом, поэтому на английском
**************************************************************************/
/**
* @addtogroup WRAPPER_SFUNC S-Function funtions
* @ingroup MCU_WRAPPER
* @brief Дефайны и функции блока S-Function
* @details Здесь собраны функции, с которыми непосредственно работает S-Function
* @note Описание функций по большей части сгенерировано MATLAB'ом, поэтому на английском
* @{
*/
#define S_FUNCTION_NAME wrapper_inu
#define S_FUNCTION_LEVEL 2
#include "mcu_wrapper_conf.h"
#define MDL_UPDATE ///< для подключения mdlUpdate()
/**
* @brief Update S-Function at every step of simulation
* @param S - pointer to S-Function (library struct from "simstruc.h")
* @details Abstract:
* This function is called once for every major integration time step.
* Discrete states are typically updated here, but this function is useful
* for performing any tasks that should only take place once per
* integration step.
*/
static void mdlUpdate(SimStruct *S)
{
// get time of simulation
time_T TIME = ssGetT(S);
//---------------SIMULATE MCU---------------
MCU_Step_Simulation(S, TIME); // SIMULATE MCU
//------------------------------------------
}//end mdlUpdate
/**
* @brief Writting outputs of S-Function
* @param S - pointer to S-Function (library struct from "simstruc.h")
* @details Abstract:
* In this function, you compute the outputs of your S-function
* block. Generally outputs are placed in the output vector(s),
* ssGetOutputPortSignal.
*/
static void mdlOutputs(SimStruct *S)
{
SIM_writeOutputs(S);
}//end mdlOutputs
#define MDL_CHECK_PARAMETERS /* Change to #undef to remove function */
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
static void mdlCheckParameters(SimStruct *S)
{
int i;
// Проверяем и принимаем параметры и разрешаем или запрещаем их менять
// в процессе моделирования
for (i=0; i<1; i++)
{
// Input parameter must be scalar or vector of type double
if (!mxIsDouble(ssGetSFcnParam(S,i)) || mxIsComplex(ssGetSFcnParam(S,i)) ||
mxIsEmpty(ssGetSFcnParam(S,i)))
{
ssSetErrorStatus(S,"Input parameter must be of type double");
return;
}
// Параметр м.б. только скаляром, вектором или матрицей
if (mxGetNumberOfDimensions(ssGetSFcnParam(S,i)) > 2)
{
ssSetErrorStatus(S,"Параметр м.б. только скаляром, вектором или матрицей");
return;
}
// sim_dt = mxGetPr(ssGetSFcnParam(S,0))[0];
// Parameter not tunable
// ssSetSFcnParamTunable(S, i, SS_PRM_NOT_TUNABLE);
// Parameter tunable (we must create a corresponding run-time parameter)
ssSetSFcnParamTunable(S, i, SS_PRM_TUNABLE);
// Parameter tunable only during simulation
// ssSetSFcnParamTunable(S, i, SS_PRM_SIM_ONLY_TUNABLE);
}//for (i=0; i<NPARAMS; i++)
}//end mdlCheckParameters
#endif //MDL_CHECK_PARAMETERS
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 1);
// Кол-во ожидаемых и фактических параметров должно совпадать
if(ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S))
{
// Проверяем и принимаем параметры
mdlCheckParameters(S);
}
else
{
return;// Parameter mismatch will be reported by Simulink
}
// set up discrete states
ssSetNumContStates(S, 0); // number of continuous states
ssSetNumDiscStates(S, DISC_STATES_WIDTH); // number of discrete states
// set up input port
if (!ssSetNumInputPorts(S, 1)) return;
for (int i = 0; i < IN_PORT_NUMB; i++)
ssSetInputPortWidth(S, i, IN_PORT_WIDTH);
ssSetInputPortDirectFeedThrough(S, 0, 0);
ssSetInputPortRequiredContiguous(S, 0, 1); // direct input signal access
// set up output port
if (!ssSetNumOutputPorts(S, OUT_PORT_NUMB)) return;
for (int i = 0; i < OUT_PORT_NUMB; i++)
ssSetOutputPortWidth(S, i, OUT_PORT_WIDTH);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork( S, 5); // number of real work vector elements
ssSetNumIWork( S, 5); // number of integer work vector elements
ssSetNumPWork( S, 0); // number of pointer work vector elements
ssSetNumModes( S, 0); // number of mode work vector elements
ssSetNumNonsampledZCs( S, 0); // number of nonsampled zero crossings
ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE);
/* Take care when specifying exception free code - see sfuntmpl.doc */
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
/**
* @brief Initialize S-Function at start of simulation
* @param S - pointer to S-Function (library struct from "simstruc.h")
* @details Abstract:
* This function is called once at start of model execution. If you
* have states that should be initialized once, this is the place
* to do it.
*/
static void mdlStart(SimStruct *S)
{
SIM_Initialize_Simulation();
}
#endif // MDL_START
/**
* @brief Initialize Sample Time of Simulation
* @param S - pointer to S-Function (library struct from "simstruc.h")
* @details Abstract:
* This function is used to specify the sample time(s) for your
* S-function. You must register the same number of sample times as
* specified in ssSetNumSampleTimes.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
// Шаг дискретизации
hmcu.SimSampleTime = mxGetPr(ssGetSFcnParam(S,NPARAMS-1))[0];
// Register one pair for each sample time
ssSetSampleTime(S, 0, hmcu.SimSampleTime);
ssSetOffsetTime(S, 0, 0.0);
}
/**
* @brief Terminate S-Function at the end of simulation
* @param S - pointer to S-Function (library struct from "simstruc.h")
* @details Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{
hmcu.fMCU_Stop = 1;
ResumeThread(hmcu.hMCUThread);
WaitForSingleObject(hmcu.hMCUThread, 10000);
SIM_deInitialize_Simulation();
mexUnlock();
}
/** WRAPPER_SFUNC
* @}
*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a
MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration
function */
#endif