Simulink代码生成(二十二)——TSP开发之创建外部设备模块
一、C Mex Sfunction文件解读
以ds18b20为例编写的C Mex S-function模块内容如下
/*=====================================*
* Required setup for C MEX S-Function *
*=====================================*/
/**** S_FUNCTION_NAME ****/
#define S_FUNCTION_NAME sfunar_ds18b20
#define S_FUNCTION_LEVEL 2
/* define error messages */
#define ERR_INVALID_SET_INPUT_DTYPE_CALL \
"Invalid call to mdlSetInputPortDataType"
#define ERR_INVALID_SET_OUTPUT_DTYPE_CALL \
"Invalid call to mdlSetOutputPortDataType"
#define ERR_INVALID_DTYPE "Invalid input or output port data type"
enum
{
PIN = 0,
DEVICE_INDEX,
NUMS_PARAM
};
/*========================*
* General Defines/macros *
*========================*/
#define PIN(S) ssGetSFcnParam(S, PIN)
#define DEVICE_INDEX(S) ssGetSFcnParam(S, DEVICE_INDEX)
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* Initialize the sizes array
*/
static void mdlInitializeSizes(SimStruct *S)
{
/* Set and Check parameter count */
ssSetNumSFcnParams(S, NUMS_PARAM); //有两个输入参数
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;
/* Set the parameter's tunable status */
for(int i = 0; i < NUMS_PARAM; i++)
{
ssSetSFcnParamTunable(S, i, SS_PRM_NOT_TUNABLE); //输入参数都设为不可调
}
// No input and output
if (!ssSetNumInputPorts(S, 0)) { //没有输入
return;
}
if (!ssSetNumOutputPorts(S, 1)) { // 1个输出
return;
}
ssSetOutputPortWidth(S,0,1); //输出维度为1
ssSetOutputPortSampleTime(S, 0, INHERITED_SAMPLE_TIME); //继承采样
ssSetOutputPortOffsetTime(S, 0, 0.0);
ssSetOutputPortDataType(S,0 ,SS_DOUBLE); //输出数据类型为double
/* sample times */
ssSetNumSampleTimes(S, 1); //1种采样时间
//ssSetInputPortDirectFeedThrough(S, 0, 1); //没有输入,没有直接馈入
/* options */
ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME));
} /* end mdlInitializeSizes */
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* Initialize the sample times array.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
} /* end mdlInitializeSampleTimes */
/* Function: mdlOutputs =======================================================
* Abstract:
* Compute the outputs of the S-function.
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
} /* end mdlOutputs */
/* Function: mdlTerminate =====================================================
* Abstract:
* Called when the simulation is terminated.
*/
static void mdlTerminate(SimStruct *S)
{
UNUSED_PARAMETER(S);
} /* end mdlTerminate */
#define MDL_RTW
#if defined(MATLAB_MEX_FILE) && defined(MDL_RTW)
/* Function: mdlRTW =======================================================
* Abstract:
* This function is called when the Real-Time Workshop is generating
* the model.rtw file.
*/
static void mdlRTW(SimStruct *S)
{
int_T c_pin = (int) (mxGetScalar(PIN(S))); //获取参数1,c文件中用c_xx,tlc文件中用t_xx,习惯写法便于区分
int_T c_device_index = (int) (mxGetPr(DEVICE_INDEX(S))[0]); //获取参数2
if (!ssWriteRTWParamSettings(S, NUMS_PARAM,
SSWRITE_VALUE_DTYPE_NUM, "r_pin", &c_pin, DTINFO(SS_INT8, COMPLEX_NO),
SSWRITE_VALUE_DTYPE_NUM, "r_device_index", &c_device_index, DTINFO(SS_INT8, COMPLEX_NO)))
{
/* An error occurred which will be reported */
}
}
#endif
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
# include "simulink.c" /* MEX-file interface mechanism */
//# include "fixedpoint.c" /* needed when it is configured with fixdt data type */
#else /* Prevent usage by RTW if TLC file is not found */
#include "cg_sfun.h" /* Code generation registration function */
#endif
!ssWriteRTWParamSettings(S, NUMS_PARAM,
SSWRITE_VALUE_DTYPE_NUM, “r_pin”, &c_pin, DTINFO(SS_INT8, COMPLEX_NO),
SSWRITE_VALUE_DTYPE_NUM, “r_device_index”, &c_device_index, DTINFO(SS_INT8, COMPLEX_NO))
上面这句是最核心的,可以参考matlab的help:
ssWriteRTWParamSettings用法
在tlc中访问C Mex S中的变量用这种方式