sfun.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * @file controller.c
  3. * @author Xiao Lifan (xiaolf6@midea.com)
  4. * @brief 仿真s-function主文件
  5. * @version 0.1
  6. * @date 2022-04-08
  7. *
  8. * @copyright Copyright (c) 2022
  9. *
  10. */
  11. /*
  12. * You must specify the S_FUNCTION_NAME as the name of your S-function
  13. * (i.e. replace sfuntmpl_basic with the name of your S-function).
  14. */
  15. #define S_FUNCTION_NAME sim_board
  16. #define S_FUNCTION_LEVEL 2
  17. /*
  18. * Need to include simstruc.h for the definition of the SimStruct and
  19. * its associated macro definitions.
  20. */
  21. #include "simstruc.h"
  22. #include "sfun_wrapper.h"
  23. int injection_dtype_id;
  24. /* Function: mdlInitializeSizes ===============================================
  25. * Abstract:
  26. * The sizes information is used by Simulink to determine the S-function
  27. * block's characteristics (number of inputs, outputs, states, etc.).
  28. */
  29. static void mdlInitializeSizes(SimStruct *S)
  30. {
  31. /* Register Simulink Bus Data Types */
  32. ssRegisterTypeFromNamedObject(S, "sfunc_injection", &injection_dtype_id);
  33. /* One expected parameters which is sample time */
  34. ssSetNumSFcnParams(S, 1);
  35. if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
  36. {
  37. /* Return if number of expected != number of actual parameters */
  38. return;
  39. }
  40. /* Set the first parameter non-tunable */
  41. ssSetSFcnParamTunable(S, 0, 0);
  42. /* Set no continuous and discrete state */
  43. ssSetNumContStates(S, 0);
  44. ssSetNumDiscStates(S, 0);
  45. /* Set 2 input port, 1 for analog input, 1 for digital input*/
  46. if (!ssSetNumInputPorts(S, 3))
  47. return;
  48. /* Analog input port width 8 */
  49. ssSetInputPortWidth(S, 0, 16);
  50. /*direct input signal access*/
  51. ssSetInputPortRequiredContiguous(S, 0, true);
  52. ssSetInputPortDirectFeedThrough(S, 0, 1);
  53. /* Digital input port width 8 */
  54. ssSetInputPortWidth(S, 1, 8);
  55. /* Digital input port data type INT32*/
  56. ssSetInputPortDataType(S, 1, SS_INT32);
  57. /*direct input signal access*/
  58. ssSetInputPortRequiredContiguous(S, 1, true);
  59. ssSetInputPortDirectFeedThrough(S, 1, 1);
  60. /* Injection input port width 8 */
  61. ssSetInputPortWidth(S, 2, 8);
  62. /* Injection control port data type INT32 */
  63. ssSetInputPortDataType(S, 2, injection_dtype_id);
  64. /*direct input signal access*/
  65. ssSetInputPortRequiredContiguous(S, 2, true);
  66. ssSetInputPortDirectFeedThrough(S, 2, 1);
  67. ///* Injection data input port width 8 */
  68. // ssSetInputPortWidth(S, 3, 8);
  69. ///*direct input signal access*/
  70. // ssSetInputPortRequiredContiguous(S, 3, true);
  71. // ssSetInputPortDirectFeedThrough(S, 3, 1);
  72. /* Set 2 output port, 1 for analog output, 1 for digital input */
  73. if (!ssSetNumOutputPorts(S, 3))
  74. return;
  75. /* Analog output port width 8 */
  76. ssSetOutputPortWidth(S, 0, 8);
  77. /* Digital output port width 16 */
  78. ssSetOutputPortWidth(S, 1, 16);
  79. /* Digital input port data type INT32*/
  80. ssSetOutputPortDataType(S, 1, SS_INT32);
  81. /* Test point data output port width 32 */
  82. ssSetOutputPortWidth(S, 2, 32);
  83. ssSetNumSampleTimes(S, 1);
  84. ssSetNumRWork(S, 0);
  85. ssSetNumIWork(S, 0);
  86. ssSetNumPWork(S, 0);
  87. ssSetNumModes(S, 0);
  88. ssSetNumNonsampledZCs(S, 0);
  89. /* Specify the operating point save/restore compliance to be same as a
  90. * built-in block */
  91. ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);
  92. ssSetOptions(S, 0);
  93. }
  94. /* Function: mdlInitializeSampleTimes =========================================
  95. * Abstract:
  96. * This function is used to specify the sample time(s) for your
  97. * S-function. You must register the same number of sample times as
  98. * specified in ssSetNumSampleTimes.
  99. */
  100. static void mdlInitializeSampleTimes(SimStruct *S)
  101. {
  102. const real_T *ts = mxGetPr(ssGetSFcnParam(S, 0));
  103. ssSetSampleTime(S, 0, ts[0]);
  104. ssSetOffsetTime(S, 0, 0.0);
  105. }
  106. #define MDL_START /* Change to #undef to remove function */
  107. #if defined(MDL_START)
  108. /* Function: mdlStart =======================================================
  109. * Abstract:
  110. * This function is called once at start of model execution. If you
  111. * have states that should be initialized once, this is the place
  112. * to do it.
  113. */
  114. static void mdlStart(SimStruct *S)
  115. {
  116. McuInit(ssGetSampleTime(S, 0));
  117. }
  118. #endif /* MDL_START */
  119. /* Function: mdlOutputs =======================================================
  120. * Abstract:
  121. * In this function, you compute the outputs of your S-function
  122. * block.
  123. */
  124. static void mdlOutputs(SimStruct *S, int_T tid)
  125. {
  126. const real_T *ain = (const real_T *)ssGetInputPortSignal(S, 0);
  127. const int32_T *din = (const int32_T *)ssGetInputPortSignal(S, 1);
  128. const injection_dtype *ctrl = (const injection_dtype *)ssGetInputPortSignal(S, 2);
  129. // const real_T* data = (const real_T*)ssGetInputPortSignal(S, 3);
  130. real_T *aout = ssGetOutputPortSignal(S, 0);
  131. int32_T *dout = ssGetOutputPortSignal(S, 1);
  132. real_T *wout = ssGetOutputPortSignal(S, 2);
  133. McuRun(ain, din, ctrl, aout, dout, wout);
  134. }
  135. #define MDL_UPDATE /* Change to #undef to remove function */
  136. #if defined(MDL_UPDATE)
  137. /* Function: mdlUpdate ======================================================
  138. * Abstract:
  139. * This function is called once for every major integration time step.
  140. * Discrete states are typically updated here, but this function is useful
  141. * for performing any tasks that should only take place once per
  142. * integration step.
  143. */
  144. static void mdlUpdate(SimStruct *S, int_T tid)
  145. {}
  146. #endif /* MDL_UPDATE */
  147. /* Function: mdlTerminate =====================================================
  148. * Abstract:
  149. * In this function, you should perform any actions that are necessary
  150. * at the termination of a simulation. For example, if memory was
  151. * allocated in mdlStart, this is the place to free it.
  152. */
  153. static void mdlTerminate(SimStruct *S)
  154. {}
  155. /*=============================*
  156. * Required S-function trailer *
  157. *=============================*/
  158. #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
  159. #include "simulink.c" /* MEX-file interface mechanism */
  160. #else
  161. #include "cg_sfun.h" /* Code generation registration function */
  162. #endif