同一个 S-Function 使用了两次,一个有效,一个无效

Same S-Function used twice, one works one doesn't

我有一个 simulink 模型,我制作了一个简单的 s-function 块来添加到我的模型中并且它可以工作。 如果我在我的模型中复制或使用相同的 s-function 两次,当我 运行 它只有最后一个调用的 s-function 会做它应该做的事情时,另一个会输出 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 个库块,我得到了相同的结果

您正在定义这些变量:

float32 DivByZeroInput;
float32 DivByZeroOutput;

const void * inputPorts[NUMBER_OF_INPUTS];
const void * outputPorts[NUMBER_OF_OUTPUTS];

这些变量在两个实例之间共享,这意味着两个 S-Function 写入相同的输出地址。

旁注:您真的必须使用 S-Function 吗?从几个本地 simulink 块创建相同的东西可能要容易得多。