主要内容

创建和更新s -函数运行时参数

关于运行时参数

您可以创建调用的外部s函数对话框参数的内部表示运行时参数.每个运行时参数对应于一个或多个对话框参数,可以具有与其对应的外部参数相同的值和数据类型,也可以具有不同的值或数据类型。如果运行时参数的值或数据类型与外部对应参数不同,则称对话框参数已转换为创建运行时参数。与多个对话框参数相对应的运行时参数的值通常是对话框参数值的函数。的仿真软金宝app件®引擎为运行时参数分配和释放存储,并提供用于更新和访问它们的功能,从而消除了S函数的需要执行这些任务。运行时参数有助于以下类型的S函数操作:

  • 计算参数

    一个块的输出通常是几个对话框参数值的函数。例如,假设一个块有两个参数,某个物体的体积和密度,块的输出是输入信号和物体质量的函数。在这种情况下,质量可以看作是由体积和密度这两个外部参数计算出来的第三个内部参数。s函数可以创建与计算权重对应的运行时参数,从而无需在输出计算中为权重提供特殊情况处理。看到从多个S函数参数创建运行时参数了解更多信息。

  • 数据类型转换

    通常,块需要更改对话框参数的数据类型以促进内部处理。例如,假设块的输出是输入的函数,并且对话框参数,输入和对话框参数是不同的数据类型。在这种情况下,S函数可以创建具有与对话框参数相同的运行时参数,但具有输入信号的数据类型,并在输出的计算中使用运行时参数。

  • 代码生成

    在代码生成期间,金宝appSimulink Coder™产品将所有运行时参数自动写入模型.rtw文件,消除了S-函数的需要通过一个通过一个执行此任务mdlRTW方法。

sfcndemo_runtime.金宝appsimulink模型包含创建运行时参数的四个示例S函数。

创建运行时参数

在一个c.S函数,您可以以多种方式创建运行时参数。以下部分描述了在C S函数中创建运行时参数的不同方法。

一次创建运行时参数

使用酝酿函数ssregalltunableparamsasruntimeparams.mdlsetworkwidths.创建对应于所有可调参数的运行时参数。此函数要求您将其传递一系列名称,一个用于每个运行时参数。这金宝appSimulink编码器产品使用这些名称作为代码生成期间参数的名称。S函数sfun_runtime1.c.显示如何一次创建运行时参数。

这种创建运行时参数的方法假设s函数运行时参数与其可调对话框参数之间存在一对一的对应关系。事实可能并非如此。例如,s函数可能希望使用一个计算参数,该参数的值是由多个对话框参数组成的函数。在这种情况下,s函数可能需要单独创建运行时参数。

单独创建运行时参数

单独创建运行时参数,S函数mdlsetworkwidths.方法应该

  1. 指定它打算使用的运行时参数的数量sssetnumruntimeparams.

  2. 使用ssRegDlgParamAsRunTimeParam注册与单个对话框参数对应的运行时参数,即使存在数据类型转换,也可以sssetruntimeparaminfo.设置与多个对话框参数相对应的运行时参数的属性。

以下示例使用ssRegDlgParamAsRunTimeParam并从S函数中获取sfun_runtime3.c..此示例直接从对话框参数创建运行时参数,以及与第一个输入端口的信号相同的数据类型。

static void mdlSetWorkWidths(SimStruct *S){/*获取用于运行时参数的输入数据类型*/ DTypeId dtId = ssGetInputPortDataType(S, 0);/*定义运行时参数的名称*/ const char_T *rtParamName = "增益";ssSetNumRunTimeParams (S, 1);/*一个运行时参数*/ if (ssGetErrorStatus(S) != NULL) return;ssRegDlgParamAsRunTimeParam(S, GAIN_IDX, 0, rtParamName, dtId);} #endif /* MDL_SET_WORK_WIDTHS */

下一个示例使用sssetruntimeparaminfo.并从S函数中获取sfun_runtime2.c

静态void mdlsetworkwidths(Simstruct * s){ssparamrec p;/ *初始化ssparamrec结构* / int dlgp = gain_idx;/ * S函数参数索引* / / *配置运行时参数信息* / p.name =“增益”;p.ndimensions = 2;p.dimensions =(int_t *)mxgetdimensions(gain_param(s));p.datatypeid = ss_double;p.complexSignal = complex_no;p.data =(void *)mxgetpr(gain_param(s));p.dataAttributes = null;p.ndlgparamindices = 1; p.dlgParamIndices = &dlgP; p.transformed = false; p.outputAsMatrix = false; /* Set number of run-time parameters */ if (!ssSetNumRunTimeParams(S, 1)) return; /* Set run-time parameter information */ if (!ssSetRunTimeParamInfo(S, 0, &p)) return; }

S函数sfun_runtime2.c定义参数gain_idx.gain_param.在使用这些参数之前mdlsetworkwidths.

#define GAIN_IDX 1 #define GAIN_PARAM(S) ssGetSFcnParam(S,GAIN_IDX)

从多个S函数参数创建运行时参数

使用sssetruntimeparaminfo.函数mdlsetworkwidths.创建运行时参数作为多个S函数参数的函数。例如,考虑具有两个S函数参数,密度和音量的S函数。S函数输入力(F)并输出加速度(一种)。这mdloutputs.方法使用等式计算力F = m *,质量(m)是密度和体积的产物。

S函数sfun_runtime4.c.使用单个运行时参数实现此示例以存储质量。S-函数通过定义运行时参数数据类型,以及与卷和密度相关联的变量开始。

#define RUN_TIME_DATA_TYPE SS_DOUBLE #if RUN_TIME_DATA_TYPE == SS_DOUBLE typef real_T RunTimeDataType;#endif #define VOL_IDX 0 #define VOL_PARAM(S) ssGetSFcnParam(S,VOL_IDX) #define DEN_IDX 1 #define DEN_PARAM(S,DEN_IDX) ssGetSFcnParam(S,DEN_IDX)

mdlsetworkwidths.然后,方法初始化运行时参数,如下所述。

静态void mdlsetworkwidths(Simstruct * s){ssparamrec p;/ *初始化SSParamrec结构* / int DLG [2];/ *存储对话框指数* / real_t vol = * mxgetpr(vol_param(s));real_t den = * mxgetpr(den_param);runtimedatatype * mass;/ *初始化运行时参数的尺寸为* local变量。Simu金宝applink引擎在运行时参数中存储此*信息的副本。* / int_t massdims [2] = {1,1};/ *为运行时参数数据分配内存。S函数*拥有此内存位置。 The Simulink engine does not copy the data.*/ if ((mass=(RunTimeDataType*)malloc(1)) == NULL) { ssSetErrorStatus(S,"Memory allocation error"); return; } /* Store the pointer to the memory location in the S-function * userdata. Since the S-function owns this data, it needs to * free the memory during mdlTerminate */ ssSetUserData(S, (void*)mass); /* Call a local function to initialize the run-time * parameter data. The Simulink engine checks that the data is not * empty so an initial value must be stored. */ calcMass(mass, vol, den); /* Specify mass as a function of two S-function dialog parameters */ dlg[0] = VOL_IDX; dlg[1] = DEN_IDX; /* Configure run-time parameter information. */ p.name = "Mass"; p.nDimensions = 2; p.dimensions = massDims; p.dataTypeId = RUN_TIME_DATA_TYPE; p.complexSignal = COMPLEX_NO; p.data = mass; p.dataAttributes = NULL; p.nDlgParamIndices = 2; p.dlgParamIndices = &dlg p.transformed = RTPARAM_TRANSFORMED; p.outputAsMatrix = false; /* Set number of run-time parameters */ if (!ssSetNumRunTimeParams(S, 1)) return; /* Set run-time parameter information */ if (!ssSetRunTimeParamInfo(S,0,&p)) return; }

本地功能calmmass.更新运行时参数值mdlsetworkwidths.和在mdlprocessparameters.,当密度或体积的值被调整。

/ *功能:Calcmass ============================================== *摘要:*本地功能计算质量​​作为音量*和密度的函数。* /静态void calcmass(runtimedattype * mass,real_t vol,real_t den){* mass = vol * den;}

mdloutputs.该方法利用所储存的质量来计算力。

/ *功能:mdlOutputs  ========================================== * 文摘:* *输出加速度作为输入力除以质量计算。*/ static void mdlOutputs(SimStruct *S, int_T tid) {real_T *y1 = ssGetOutputPortRealSignal(S,0);InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);RunTimeDataType *mass = (RunTimeDataType *)((ssGetRunTimeParamInfo(S,0))->data);/* *输出加速度=力/质量*/ y1[0] = (*uPtrs[0]) /*质量;}

最后,这是mdlterminate.方法将分配的内存释放为运行时参数mdlsetworkwidths.

/ *功能:mdlterminate ========================================== *摘要:*免费用户数据。* /静态void mdlterminate(simstruct * s){/ *可用的内存用于存储运行时参数数据* / runtimedattype * mass = ssgetuserdata;if(mass!= null){自由(质量);}}

要运行该示例,请打开Simulink模型:金宝app

更新运行时参数

每当您在仿真期间更改S函数对话框参数的值时,Simulink引擎都会调用S函数金宝appmdlCheckParameters方法验证更改。如果更改有效,则引擎调用S函数mdlprocessparameters.方法在下一个时间步骤开始时。这个方法应该更新s函数的运行时参数,以反映对话框参数的变化。

在C S函数中,使用适合于如何创建运行时参数的方法更新运行时参数,如以下部分中所述。

一次更新所有参数

在C MEX S函数中,如果S函数可调对话框参数和运行时参数之间存在一对一的对应关系,即,使用运行时参数使用ssregalltunableparamsasruntimeparams., s函数可以使用酝酿函数ssUpdateAllTunableParamsAsRunTimeParams完成这项任务。这个函数更新每个运行时参数,使其具有与相应对话框参数相同的值。看到sfun_runtime1.c.例如,

单独更新参数

如果S函数对话框和运行时参数之间没有一对一的对应关系,或者运行时参数是转换对话框参数的版本,则mdlprocessparameters.方法必须单独更新每个参数。选择用于更新运行时参数的方法,该方法根据注册方式更新运行时参数。

如果您使用sssetruntimeparaminfo., 这mdlprocessparameters.方法使用ssupdateruntimeparamdata.更新运行时参数,如sfun_runtime2.c.此函数更新参数属性记录中的数据字段,ssparamrec.,使用新的值。不能直接修改ssparamrec.,即使您可以获得指向的指针ssparamrec.使用ssGetRunTimeParamInfo

如果您使用ssRegDlgParamAsRunTimeParam, 这mdlprocessparameters.方法使用ssupdatedlgparamasruntimeparam.要更新运行时参数,如图所示sfun_runtime3.c.

更新多个s -函数参数的函数

如果将一个运行时参数注册为多个s函数参数的函数,则mdlprocessparameters.方法使用ssupdateruntimeparamdata.更新运行时参数。

S函数sfun_runtime4.c.提供一个例子。在这个例子中,mdlprocessparameters.方法计算运行时参数的新值,并将值传递给运行时参数的内存位置的指针,在呼叫期间分配mdlsetworkwidths..这mdlprocessparameters.然后通过更新的运行时参数的指针传递方法ssupdateruntimeparamdata.

调整运行时参数

调整对话框参数在模拟期间调整相应的运行时参数,并且仅在对话框参数符合以下条件时才生成的代码:

  • S-函数将对话框参数标记为可调谐,使用ssSetSFcnParamTunable

  • 对话框参数是一个MATLAB®使用Simulink产品支持的数据类型的值数组。金宝app金宝app

请注意,您无法调整运行时参数,其值是单元格数组或结构。

访问运行时参数

您可以轻松从S函数代码访问运行时参数。为了访问运行时参数数据,根据数据类型选择以下方法之一。

  • 如果数据是类型双倍的

    real_t * dataptr =(real_t *)ssgetruntimeparaminfo(s,#) - >数据;
  • 如果参数复杂,则数据的实部和虚部是交错的。例如,如果用户输入以下内容:

    k = [1 + 2i,3 + 4i;5 + 6i,7 + 8i]

    生成的矩阵是

    k = 1 + 2i 3 + 4i 5 + 6i 7 + 8i

    将此矩阵的内存布置为

    [1,2,5,6,3,4,7,8]

    要从S函数代码访问复杂的运行时参数:

    for(i = 0; i <宽度; i ++){real_t readata = dataptr [(2 * i)];real_t imagdata = dataptr [(2 * i)+1];}

笔记

矩阵元素以列 - 主要格式写出。真实和虚部的值是交错的。

也可以看看

相关话题