/* File : sfun_counter_cpp.cpp * Abstract: * * Example of an C++ S-function which stores an C++ object in * the pointers vector PWork. * * Copyright 1990-2005 The MathWorks, Inc. * $Revision: 1.4.4.6 $ */ #include #include #include "ctrl_machine.hpp" #ifdef __cplusplus extern "C" { // use the C fcn-call standard for all functions #endif // defined within this scope #define S_FUNCTION_LEVEL 2 #define S_FUNCTION_NAME air_controller /* * Need to include simstruc.h for the definition of the SimStruct and * its associated macro definitions. */ #include "simstruc.h" #define IS_PARAM_DOUBLE(pVal) (mxIsNumeric(pVal) && !mxIsLogical(pVal) &&\ !mxIsEmpty(pVal) && !mxIsSparse(pVal) && !mxIsComplex(pVal) && mxIsDouble(pVal)) /*====================* * S-function methods * *====================*/ /* Function: mdlInitializeSizes =============================================== * Abstract: * The sizes information is used by Simulink to determine the S-function * block's characteristics (number of inputs, outputs, states, etc.). */ static void mdlInitializeSizes(SimStruct *S) { /* See sfuntmpl.doc for more details on the macros below */ // This can later be used as the destination host address or similar ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ #if defined(MATLAB_MEX_FILE) if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; /* Parameter mismatch will be reported by Simulink */ } #endif if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortWidth(S, 1, 2); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 1, 1); if (!ssSetNumOutputPorts(S, 1)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortDataType(S, 0, SS_INT16); ssSetNumSampleTimes(S, PORT_BASED_SAMPLE_TIMES); ssSetInputPortSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetInputPortOffsetTime(S, 0, 0); ssSetInputPortSampleTime(S, 1, INHERITED_SAMPLE_TIME); ssSetInputPortOffsetTime(S, 1, 0); ssSetOutputPortSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOutputPortOffsetTime(S, 0, 0); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 1); // reserve element in the pointers vector ssSetNumModes(S, 0); // to store a C++ object ssSetNumNonsampledZCs(S, 0); ssSetOptions(S, 0); } /* Function: mdlInitializeSampleTimes ========================================= * 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) { } #define MDL_START /* Change to #undef to remove function */ #if defined(MDL_START) /* Function: mdlStart ======================================================= * 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) { ssGetPWork(S)[0] = (void *) new Controller; // store new C++ object in the } // pointers vector #endif /* MDL_START */ /* Function: mdlOutputs ======================================================= * Abstract: * In this function, you compute the outputs of your S-function * block. */ static void mdlOutputs(SimStruct *S, int_T tid) { InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); double ii = *uPtrs[0]; uPtrs = ssGetInputPortRealSignalPtrs(S, 1); /* Retrieve C++ object from the pointers vector and use * member functions of the object */ Controller *c = (Controller *) ssGetPWork(S)[0]; if( *uPtrs[0] != false ) { /* Switch is ON */ if( false == c->m_switch ) { std::cerr << "Turning ON" << std::endl; c->toggleSwitch(); } } else { /* Switch is OFF */ if( true == c->m_switch ) { std::cerr << "Turning OFF" <toggleSwitch(); } } c->setTemp(ii); int16_T *y = (int16_T*) ssGetOutputPortSignal(S,0); y[0] = c->getAirFlow(); UNUSED_ARG(tid); } /* Function: mdlTerminate ===================================================== * 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) { Controller *c = (Controller *) ssGetPWork(S)[0]; // retrieve and destroy C++ std::cerr << "At Termination, temp = " << c->m_temp << std::endl; delete c; // object in the termination } // function /*======================================================* * See sfuntmpl.doc for the optional S-function methods * *======================================================*/ /*=============================* * Required S-function trailer * *=============================*/ #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 #ifdef __cplusplus } // end of extern "C" scope #endif