Simulink:如何在2级s函数中使用局部变量?

时间:2014-07-18 10:02:48

标签: c matlab simulink s-function

我在C中编写了一个Simulink S函数(Level 2)。生成的块有一个输出和一个参数。此参数存储在变量中,该变量在设置块后立即在文件范围定义:

#define NUM_PARAMS 1
#define NUM_INPORTS 0
#define NUM_OUTPORTS 1

unsigned short int MASK_INDEX;

我在mdlInitializeSizes中分配它,并对其值进行一些操作:

static void mdlInitializeSizes(SimStruct *S) {  
    // Check Parameters
    ssSetNumSFcnParams(S, NUM_PARAMS);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
            return;
    }

    MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));

    (...) operations
}

我的问题是,变量MASK_INDEX似乎是全局的,并且在相同类型的所有块之间共享。因此,它对所有块保持相同的值。

作为一种解决方法,我每次都重新加载它,并重新执行操作,例如:

static void mdlOutputs(SimStruct *S, int_T tid) {
    MASK_INDEX = *mxGetPr(ssGetSFcnParam(S, 0));

    (...) operations
}

如何获得真正的“局部变量”,这样我每次都不必重复所有这些?

1 个答案:

答案 0 :(得分:2)

您还没有提到您声明MASK_INDEX的位置,但是根据您的说明,它听起来像是在文件范围内。如果是,那么是的,这个变量将在所有实例之间共享。这不是以任何方式与S-Functions隔离的,它是大多数(如果不是全部)平台上的共享库的行为方式。共享库的单个实例将由应用程序加载,在本例中为MATLAB;因此,只有一个全局变量副本。

最简单的选择是每次要访问参数时都使用ssGetSFcnParam。如果您深入研究这些S-Function宏,他们只是访问SimStruct的字段,因此重复访问不太可能导致性能下降。我甚至已经看到用于包装常用用例的宏,例如你的用例。

如果你真的想要缓存对话框参数,最简单的可能就是使用ssSetUserData。声明包含struct成员的MASK_INDEX(您不 使用struct但这种方法更具扩展性。使用mxMalloc中的mdlStart动态分配实例,并将其分配给块的用户数据。请务必在ssSetOptions的{​​{1}}来电中设置SS_OPTION_CALL_TERMINATE_ON_EXIT。然后使用mdlInitializeSizesmdlTerminate定义struct函数,在其中您将访问已分配的ssGetUserData。现在,您可以使用mxFree访问struct中的mdlOutputs个成员。

还有其他更高级的选项,例如work vectors,可能是PWork vector

另一个选项,如果您的参数是可调参数,则使用runtime parameters,它允许您缓存并可选地转换块的对话框参数。

在您的情况下,我只是坚持在ssGetUserData内每次使用ssGetSFcnParam