Documentation

DWork Vector Examples

General DWork Vector

这S-functionsfun_rtwdwork.cshows how to configure a DWork vector for use with the金宝app®Coder™product. The Simulink modelsfcndemo_sfun_rtwdworkuses this S-function to implement a simple accumulator.

这following portion of themdlInitializeSizes见过hod initializes the DWork vector and all code generation properties associated with it.

sssetnumdwork(s,1);ssSetDWorkWidth(S, 0, 1); ssSetDWorkDataType(S, 0, SS_DOUBLE); /* Identifier; free any old setting and update */ id = ssGetDWorkRTWIdentifier(S, 0); if (id != NULL) { free(id); } id = malloc(80); mxGetString(ID_PARAM(S), id, 80); ssSetDWorkRTWIdentifier(S, 0, id); /* Type Qualifier; 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-function initializes the DWork vector inmdlinitializeconditions

#define mdl_initialize_conditions / *函数:mdlinitializeconditions ========================================= * *mdlinitializeconditions(simStruct *s){real_t *x =(real_t *)ssgetDwork(s,0);/ *将DWork初始化为0 */ x [0] = 0.0;}

mdlOutputs见过hod assigns the DWork vector value to the S-function output.

/ *函数:mdlOutputs ========================================== y y y y y= x */ static void mdlOutputs(SimStruct *S, int_T tid) { real_T *y = ssGetOutputPortRealSignal(S,0); real_T *x = (real_T*) ssGetDWork(S,0); /* Return the current state as the output */ y[0] = x[0]; }

mdlUpdate见过hod increments the DWork value by the input.

#define mdl_update /*函数:mdlupdate ================================================== *摘要: *每个主要集成 *时间步长一次调用此功能。离散状态通常在此处进行更新,但是 *此功能对于执行应当 *仅进行一次每集成步骤进行一次任务很有用。*/ static void mdlupdate(simStruct *s,int_t tid){real_t *x =(real_t *)ssgetDwork(s,0);InputRealPtrStype uptrs = ssgetInputporterSignalPtrs(s,0);/ * *通过输入 * u将状态定义为u(element)( * uptrs [element]) */ x [0] += u(0);}

DWork Scratch Vector

以下示例使用刮擦DWork向量存储静态变量值。这mdlInitializeSizes见过hod configures the width and data type of the DWork vector. ThessSetDWorkUsageTypemacro then specifies the DWork vector is a scratch vector.

sssetnumdwork(s,1);ssSetDWorkWidth(S, 0, 1); ssSetDWorkDataType(S, 0, SS_DOUBLE); ssSetDWorkUsageType(S,0, SS_DWORK_USED_AS_SCRATCH);

其余的s功能完全使用划痕dwork矢量,就像其他任何类型的dwork矢量一样。这InitializeConditions见过hod sets the initial value and themdlOutputs见过hod uses the value stored in the DWork vector.

#define mdl_initialize_conditions / *函数:mdlinitializeconditions =========================================================================={real_t *x =(real_t *)ssgetDwork(s,0);/ *将DWork初始化为0 */ x [0] = 0.0;} /*函数:mdloutputs ==================================================== */ static void mdlOutputs(simStruct *s,int_t tid){real_t *y = ssgetOutputputporterPortRealSignal(s,s,0);real_t *x1 =(real_t *)ssgetDwork(s,1);x [0] = 2000;y [0] = x [0] * 2;}

If you haveSimulink Coder, 这Simulink Codersoftware handles scratch DWork differently from other DWork vectors when generating code for inlined S-function. To inline the S-function, create the following Target Language Compiler (TLC) file to describe themdlOutputs见过hod.

%implements sfun_dscratch "C" %% Function: Outputs ========================================================== %% /* dscratch Block: % */ % = 2000.0; % = % * 2;

When theSimulink Codersoftware generates code for the model, it inlines the S-function and declares the second DWork vector as a local scratch vector. For example, the model outputs function contains the following lines:

/ *本地抓DWork变量* / real_T SFunction_DWORK1; SFunction_DWORK1 = 2000.0;

If the S-function used a general DWork vector instead of a scratch DWork vector, generating code with the same TLC file would have resulted in the DWork vector being included in the data structure, as follows:

sfcndemo_dscratch_DWork.SFunction_DWORK1 = 2000.0;

DState Work Vector

此示例重写S功能exampledsfunc.cto use a DState vector instead of an explicit discrete state vector. ThemdlInitializeSizesmacro initializes the number of discrete states as zero and, instead, initializes one DWork vector.

mdlInitializeSizes见过hod then configures the DWork vector as a DState vector using a call tosssetdworksusedasdstate。This is equivalent to calling thessSetDWorkUsageTypemacro with the valueSS_DWORK_USED_AS_DSTATE。这mdlInitializeSizes见过hod sets the width and data type of the DState vector and gives the state a name usingsssetDworkname

笔记

DWork vectors configured as DState vectors must be assigned a name for the Simulink engine to register the vector as discrete states. The functionSimulink.BlockDiagram.getInitialStates(mdlreturns the assigned name in thelabelfield for the initial states.

静态void mdlinitializizes(simstruct *s){sssetnumsfcnparams(s,0);/ *预期参数的数量 */ if(ssgetNumSfcnParams(s)!= ssgetSfcnParamScount(s)){return;/ * simulink引擎报告的参数不匹配 */} sssetNumCon金宝apptstates(s,0);sssetnumdiscstates(s,0);如果(!sssetNuminputports(s,1))返回;sssetInputPortWidth(S,0,2);sssetInputPortDirectFeedThrough(s,0,1);if(!sssetNumoutputports(s,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 /* Function: mdlInitializeConditions =============================== * Abstract: * Initialize both discrete states to one. */ static 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见过hod then uses the values stored in the DState vector to compute the output of the discrete state-space equation.

/ *函数:mdlOutputs ========================================== y y y y y= cx + du */ static void mdlOutputs(simstruct *s,int_t tid){real_t *y = ssgetOutputputporportorterSignal(s,0);real_t *x =(real_t *)ssgetDwork(s,0);InputRealPtrStype uptrs = ssgetInputporterSignalPtrs(s,0);Unused_arg(tid);/*未在单个任务模式中使用*//*y = cx+du*/ y [0] = c [0] [0]*x [0]+c [0] [1] [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)*u(0)+d [1] [1] [1]]*u(1);}

最后,mdlUpdate见过hod updates the DState vector with new values for the discrete states.

#define mdl_update /*函数:mdlupdate ================================================== *摘要: * xdot = ax + bu */ static void mdlupdate(simStruct * s,int_t tid){real_t tempx [2] = {0.0,0.0,0.0};real_t *x =(real_t *)ssgetDwork(s,0);InputRealPtrStype uptrs = ssgetInputporterSignalPtrs(s,0);Unused_arg(tid);/*未在单个任务模式中使用*//*xdot = ax+bu*/ tempx [0] = a [0] [0]*x [0]+a [0] [1]*x [1]+B [0] [0]*U(0)+B [0] [1]*U(1);tempx [1] = a [1] [0]*x [0]+a [1] [1]*x [1]+b [1] [0]*u(0)*u(0)+b [1] [1] [1]]*u(1);x [0] = tempx [0];x [1] = tempx [1];}

DWORD模式向量

此示例重写S功能sfun_zc.cto use a DWork mode vector instead of an explicit mode work vector (see基本工作向量有关模式工作向量的更多信息)。该S功能实现了绝对值块。

mdlInitializeSizes见过hod sets the number of DWork vectors and zero-crossing vectors (see零交叉)toDYNAMICALLY_SIZED。这DYNAMICALLY_SIZEDsetting allows the Simulink engine to defer specifying the work vector sizes until it knows the dimensions of the input, allowing the S-function to support an input with an arbitrary width.

静态void mdlinitializizes(simstruct *s){sssetnumsfcnparams(s,0);if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; /* Parameter mismatch reported by the Simulink engine */ } ssSetNumContStates( S, 0); ssSetNumDiscStates( S, 0); if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetInputPortDirectFeedThrough(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 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); }

这Simulink engine initializes the number of zero-crossing vectors and DWork vectors to the number of elements in the signal coming into the first S-function input port. The engine then calls themdlSetWorkWidths方法,使用ssgetnumdwork确定初始化了多少个DWORD向量,然后为每个DWork矢量设置属性。

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

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

static void mdlOutputs(SimStruct *S, int_T tid) { int_T i; InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); int_T width = ssGetOutputPortWidth(S,0); boolean_T *mode = ssGetDWork(S,0); UNUSED_ARG(tid); /* not used in single tasking mode */ if (ssIsMajorTimeStep(S)) { for (i = 0; i < width; i++) { mode[i] = (boolean_T)(*uPtrs[i] >= 0.0); } } for (i = 0; i < width; i++) { y[i] = mode[i]? (*uPtrs[i]): -(*uPtrs[i]); } }