我有一个simulink模型,我制作了一个简单的s函数块添加到我的模型中,并且可以工作。 如果我在模型中两次复制或使用相同的s函数,当我运行它时,只有最后一个被调用的s函数会执行应做的操作,而另一个将输出0,这会导致捕获。
#define S_FUNCTION_NAME DivByZero
#define S_FUNCTION_LEVEL 2
#define NUMBER_OF_INPUTS 1
#define NUMBER_OF_OUTPUTS 1
#include "DivByZero.h"
#include "mex.h"
#if !defined(MATLAB_MEX_FILE)
/*
* This file cannot be used directly
*/
# error This_file_can_be_used_only_during_simulation_inside_Simulink
#endif
float32 DivByZeroInput;
float32 DivByZeroOutput;
const void * inputPorts[NUMBER_OF_INPUTS];
const void * outputPorts[NUMBER_OF_OUTPUTS];
static void mdlInitializeSizes(SimStruct *S)
{
uint8 i;
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
{
return; /* Parameter mismatch reported by the Simulink engine */
}
if (!ssSetNumInputPorts(S, NUMBER_OF_INPUTS)) return;
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortDataType(S, 0, SS_SINGLE);
for (i = 0; i < NUMBER_OF_INPUTS; i++)
{
ssSetInputPortDirectFeedThrough(S, i, 1); /* Set direct feedthrough flag */
ssSetInputPortRequiredContiguous(S, i, 1); /*direct input signal access*/
}
if (!ssSetNumOutputPorts(S, NUMBER_OF_OUTPUTS)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortDataType(S, 0, SS_SINGLE);
/* Set Sample Time */
ssSetNumSampleTimes(S, 1);
/* Specify the sim state compliance to be same as a built-in block */
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetOptions(S, SS_OPTION_ALLOW_PORT_SAMPLE_TIME_IN_TRIGSS);
ssSupportsMultipleExecInstances(S, true); //set so the s-function can be used in a for each subsystem block
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
/* Inherits sample time from the driving block */
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}
#define MDL_START
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
uint8 i;
/* Save Input ports */
for (i = 0; i < NUMBER_OF_INPUTS; i++)
{
inputPorts[i] = ssGetInputPortSignal(S, i);
}
/* Save Output ports */
for (i = 0; i < NUMBER_OF_OUTPUTS; i++)
{
outputPorts[i] = ssGetOutputPortRealSignal(S, i);
}
}
#endif
static void mdlOutputs(SimStruct *S, int_T tid)
{
memcpy(&DivByZeroInput, inputPorts[0], sizeof(DivByZeroInput));//gets the input port info
if (fabs(DivByZeroInput) > 0.00001f)
{
DivByZeroOutput = DivByZeroInput;
}
else
{
if (DivByZeroInput >= 0.0f)
{
DivByZeroOutput = 0.00001f;
}
else
{
DivByZeroOutput= -0.00001f;
}
}
memcpy(outputPorts[0], &DivByZeroOutput, sizeof(DivByZeroOutput));//sets the output port
}
static void mdlTerminate(SimStruct *S)
{
/* MODEL TERMINATE */
}
/* END OF TEMPLATE */
#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
从代码中可以看到,s函数应该提供零保护的简单除法。 在下图中,如果删除S-Function1,则S-Function将按预期工作。 我尝试将其放在一个库块中,然后只放入2个库块,结果相同
答案 0 :(得分:1)
您正在定义以下变量:
float32 DivByZeroInput;
float32 DivByZeroOutput;
const void * inputPorts[NUMBER_OF_INPUTS];
const void * outputPorts[NUMBER_OF_OUTPUTS];
这些变量在两个实例之间共享,这意味着两个S功能都写入相同的输出地址。
侧面说明:您真的必须使用S功能吗?从几个本地simulink块创建相同的对象可能要容易得多。