主要内容

dwork矢量例子

一般睡觉矢量

S函数sfun_rtwdwork.c展示如何配置DOWN矢量以便使用金宝app®编码器™产品。仿真软件金宝app模型sfcndemo_sfun_rtwwwwwwork.使用这个s函数来实现一个简单的累加器。

以下部分mdlInitializeSizes方法初始化DWORK矢量和与其相关联的所有代码生成属性。

ssSetNumDWork (S, 1);ssSetDWorkWidth (0, 1);ssSetDWorkDataType(年代,0,SS_DOUBLE);/ *标识符;免费任何旧设置和更新* / id = ssgetdworkrtwientifier(s,0);if(id!= null){free(id);id = malloc(80);mxgetstring(id_param(s),ID,80);sssetdworkrtwidentifier(s,0,ID);/ *键入限定符; free any old setting and update */ tq = ssGetDWorkRTWTypeQualifier(S, 0); if (tq != NULL) { free(tq); } tq = malloc(80); mxGetString(TQ_PARAM(S), tq, 80); ssSetDWorkRTWTypeQualifier(S, 0, tq); /* Storage class */ sc = ((int_T) *((real_T*) mxGetPr(SC_PARAM(S)))) - 1; ssSetDWorkRTWStorageClass(S, 0, sc);

s函数初始化DWork向量mdlInitializeConditions

#define MDL_INITIALIZE_CONDITIONS /* Function: mdlinitializeconconditions ============================ *摘要:*初始化两个连续状态为零*/ static void mdlinitializeconconditions (SimStruct *S) {real_T* x = (real_T*) ssGetDWork(S,0);/*初始化dwork为0 */ x[0] = 0.0;}

mdlOutputs方法将DWork向量值赋给s函数输出。

/ *功能:MDLOUTPUTS ======================================== *摘要:* y= x * /静态void mdloutputs(simstruct * s,int_t tid){real_t * y = ssgetoutputportrealsignal(s,0);real_t * x =(real_t *)ssgetdwork(s,0);/ *将当前状态返回为输出* / y [0] = x [0];}

mdlupdate.方法通过输入增加DWork值。

#定义MDL_UPDATE / *功能:mdlUpdate  ============================================ * 文摘:*函数被调用一次每个主要集成*时间步。离散状态通常在这里更新,但是这个函数对于执行每个集成步骤只应该发生一次的任何任务都是有用的。*/ static void mdlUpdate(SimStruct *S, int_T tid) {real_T* x = (real_T*) ssGetDWork(S,0);InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);/* *通过输入增加状态* U定义为U(element) (*uPtrs[element]) */ x[0] += U(0);}

DWork划痕向量

下面的示例使用scratch DWork向量存储静态变量值。的mdlInitializeSizes方法配置DWORK矢量的宽度和数据类型。的ssSetDWorkUsageType然后宏指定dwork矢量是划痕向量。

ssSetNumDWork (S, 1);ssSetDWorkWidth (0, 1);ssSetDWorkDataType(年代,0,SS_DOUBLE);ssSetDWorkUsageType(年代,0,SS_DWORK_USED_AS_SCRATCH);

s函数的其余部分使用scratch DWork向量,与使用任何其他类型的DWork向量完全一样。的初始化方法设置初始值和mdlOutputs方法使用存储在DWork向量中的值。

#define MDL_INITIALIZE_CONDITIONS /* Function: mdlinitializeconconditions ================================ */ static void mdlinitializeconconditions (SimStruct *S) {real_T* x = (real_T*) ssGetDWork(S,0);/*初始化dwork为0 */ x[0] = 0.0;} / *功能:mdlOutputs  ============================================= */ 静态孔隙mdlOutputs (SimStruct *年代,int_T tid) {real_T * y = ssGetOutputPortRealSignal (S, 0);real_T * x1 = (real_T *) ssGetDWork (S, 1);x [0] = 2000;Y [0] = x[0] * 2;}

如果你有金宝appSimulink编码器,金宝appSimulink编码器软件在为内联的S函数的代码生成代码时,从其他DWORK向量处理刮擦DWORK。要在内联函数,创建以下目标语言编译器(TLC)文件以描述mdlOutputs方法。

%实现sfun_dscratch“c”%%功能:输出========================================================== %% / * dscratch块:% * /%= 2000.0;% =% * 2;

当。。。的时候金宝appSimulink编码器软件为模型生成代码,它引入了S函数并将第二个dwork向量声明为本地划痕向量。例如,模型输出函数包含以下行:

/ *本地划痕dwork变量* / real_t sfunction_dwork1;sfunction_dwork1 = 2000.0;

如果s -函数使用通用的DWork向量而不是scratch DWork向量,那么用相同的TLC文件生成代码将导致DWork向量被包含在数据结构中,如下所示:

sfcndemo_dscratch_dwork.sfunction_dwork1 = 2000.0;

dstate工作量

这个例子重写了s函数的例子dsfunc.c.使用dstate向量而不是明确的离散状态向量。的mdlInitializeSizes宏初始化离散状态的数量为0,相反,初始化一个DWork向量。

mdlInitializeSizes然后,方法使用呼叫将DWORK矢量配置为DSTATE向量ssSetDWorkUsedAsDState.这相当于呼叫ssSetDWorkUsageType宏与价值ss_dwork_used_as_dstate..的mdlInitializeSizes方法设置DSTATE向量的宽度和数据类型,并使用姓名使用ssSetDWorkName

请注意

配置为dstate向量的Dwork矢量必须为Simulink引擎分配一个名称,以将向量注册为离散状态。金宝app功能金宝appsimulink.blockdiagram.getInitialStates(mdl返回分配的名称标签初始状态的场。

static void mdlinitializesize (SimStruct *S) {ssSetNumSFcnParams(S, 0);/*期望的参数个数*/ if (ssGetNumSFcnParams(S) != ssgetfcnparamscount (S)) {return;/* Simulink引擎报告的参数不匹配*/}ssSetNumContSt金宝appates(S, 0);ssSetNumDiscStates (S, 0);如果(!ssSetNumInputPorts(年代,1))返回;ssSetInputPortWidth (0, 2);ssSetInputPortDirectFeedThrough (0, 1);如果(!ssSetNumOutputPorts(年代,1))返回; ssSetOutputPortWidth(S, 0, 2); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); ssSetNumDWork(S, 1); ssSetDWorkUsedAsDState(S, 0, SS_DWORK_USED_AS_DSTATE); ssSetDWorkWidth(S, 0, 2); ssSetDWorkDataType(S, 0, SS_DOUBLE); ssSetDWorkName(S, 0, "SfunStates"); ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); }

mdlInitializeConditions方法使用返回的指针初始化DState向量值ssGetDWork

#define mdl_initialize_conditions / *功能:mdlinitializeconditions =============================== *摘要:*将两个离散状态初始化为一个。* /静态void mdlinitializeConditions(simstruct * s){real_t * x0 =(real_t *)ssgetdwork(s,0);INT_T LP;for(lp = 0; lp <2; lp ++){* x0 ++ = 1.0;}}

mdlOutputs方法然后使用存储在DState向量中的值来计算离散状态空间方程的输出。

/ *功能:mdlOutputs  ======================================== * 文摘:* y =残雪+ Du * /静态孔隙mdlOutputs (SimStruct *年代,int_T tid) {real_T * y = ssGetOutputPortRealSignal (S, 0);ssGetDWork(S, 0); / /输出InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);UNUSED_ARG (tid);/ *不习惯在单任务模式* / / * y =残雪+ Du * / y [0] = C [0] [0] * x [0] + C [0] [1] * x [1] + D [0] [0] * U (0) + D [0] [1] * U (1);y [1] = C [1] [0] * x [0] + C [1] [1] * x [1] + D [1] [0] * U (0) + D [1] [1] * U (1);}

最后,mdlupdate.方法使用离散状态的新值更新DState向量。

#定义MDL_UPDATE / *功能:mdlUpdate  ============================================ * 文摘:* xdot = Ax +布鲁里溃疡* /静态空mdlUpdate (SimStruct *年代,int_T tid) {real_T tempX [2] = {0.0, 0.0};ssGetDWork(S, 0); / /输出InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);UNUSED_ARG (tid);/ *不习惯在单任务模式* / / * xdot = Ax +布鲁里溃疡* / tempX [0] = [0] [0] * x [0] + [0] [1] B * x [1] + [0] [0] * U (0) + B [0] [1] * U (1);tempX [1] = [1] [0] * x [0] + [1] [1] B * x [1] + [1] [0] * U (0) + B [1] [1] * U (1);x [0] = tempX [0];x [1] = tempX [1];}

DWork模式向量

这个例子重写了s函数sfun_zc.c使用dwork模式向量而不是明确的模式工作向量(参见基本工作向量有关模态工作矢量的更多信息)。这个s函数实现了一个绝对值块。

mdlInitializeSizes方法设置DWork向量和零交叉向量的数量(参见零交叉)动态化.的动态化设置允许Simulink引擎推迟指定工金宝app作矢量大小,直到它知道输入的尺寸,允许S函数支持具有任意宽度的输入。金宝app

static void mdlinitializesize (SimStruct *S) {ssSetNumSFcnParams(S, 0);if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){返回;/* Simulink引擎报告的参数不匹配*/}ssSetNumContSt金宝appates(S, 0);ssSetNumDiscStates (S, 0);如果(!ssSetNumInputPorts(年代,1))返回;ssSetInputPortWidth(年代,0,DYNAMICALLY_SIZED);ssSetInputPortDirectFeedThrough (0, 1);如果(! ssSetNumOutputPorts(年代,1))返回;ssSetOutputPortWidth(年代,0,DYNAMICALLY_SIZED); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 0); ssSetNumDWork(S, 1); ssSetNumModes(S, 0); /* Initializes the zero-crossing and DWork vectors */ ssSetDWorkWidth(S,0,DYNAMICALLY_SIZED); ssSetNumNonsampledZCs(S, DYNAMICALLY_SIZED); /* Take care when specifying exception free code - see sfuntmpl_doc.c */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); }

Simu金宝applink引擎将零交叉向量和DWORK矢量的数量初始化为进入第一S函数输入端口的信号中的元素数量。然后发动机呼叫mdlsetworkwidths.方法,该方法使用ssGetNumDWork来确定初始化了多少DWork向量,然后为每个DWork向量设置属性。

#define MDL_SET_WORK_WIDTHS static void mdlSetWorkWidths(SimStruct *S) {int_T numdw = ssGetNumDWork(S);int_T我;For (i = 0;我< numdw;i++) {ssSetDWorkUsageType(S, i, SS_DWORK_USED_AS_MODE);ssSetDWorkDataType (S, i, SS_BOOLEAN);ssSetDWorkComplexSignal (S, i, COMPLEX_NO);}}

mdlOutputs方法使用存储在DWork模式向量中的值来确定输出信号应该等于输入信号还是输入信号的绝对值。

静态void mdloutputs(Simstruct * s,Int_t tid){int_t i;InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);real_t * y = ssgetoutputportrealsignal(s,0);int_t width = ssgetoutportwidth(s,0);boolean_t * mode = ssgetdwork(s,0);UNUSED_ARG (tid);/ *未用于单个任务模式* / if(ssismajortimestep(ssismajortimestep){for(i = 0; i  = 0.0);for(i = 0; i <宽度; i ++){y [i] = mode [i]?(* UPTRS [I]): - (* UPTRS [I]);}}