除了DWork矢量,Simulink金宝app®软件提供了一组简化的工作向量。在一些s函数中,这些初等功向量可以提供比使用DWork向量更简单的解:
IWork向量存储整数数据。
模式向量模型零交叉或其他需要单一模式向量的特征。
PWork向量存储指向数据结构的指针,例如s函数与遗留代码、另一个软件应用程序或硬件应用程序之间的接口。
RWork向量存储浮点(实)数据。
下表比较了每种类型的功向量与DWork向量。
工作向量类型 | 与DWork向量比较 | 如何创建等效的DWork向量 |
---|---|---|
套装 | IWork向量不能在生成的代码中自定义。而且,只允许有一个IWork向量。 |
ssSetNumDWork (S, 1);ssSetDWorkDataType(年代,0,SS_INT8); |
模式 | 模式向量比DWork向量需要更多的内存,因为模式向量总是存储在整数 数据类型。同样,你只允许一个模式向量。 |
ssSetNumDWork (S, 1);ssSetDWorkUsageType(年代,0,SS_DWORK_USED_AS_MODE);ssSetDWorkDataType(年代,0,SS_INT8); |
PWork | 与DWork向量不同,PWork向量不能在生成的代码中命名。此外,您只允许一个PWork向量。 |
ssSetNumDWork (S, 1);ssSetDWorkDataType(年代,0,SS_POINTER); |
RWork | RWork向量不能在生成的代码中自定义。此外,您只允许一个RWork向量。 |
ssSetNumDWork (S, 1);ssSetDWorkDataType(年代,0,SS_DOUBLE); |
使用初等功向量的过程与使用d功向量的过程类似(参见在C - MEX s -函数中使用DWork向量.)初等功向量的性质更少,初始化过程更简单。但是,如果您需要为s -函数生成代码,那么s -函数将比使用DWork向量更复杂。
下面的步骤说明如何建立和使用基本功向量。看到额外的矢量宏查看与以下过程中的每个步骤相关的宏列表。
在mdlInitializeSizes
,指定功向量的大小ssSetNum
宏,例如:X
工作
ssSetNumPWork (S, 2);
这个宏指示工作向量包含多少元素,但是,Simulink引擎此时并不分配内存。金宝app
s函数可以推迟指定功向量的长度,直到通过传递值可以获得关于s函数输入的所有信息DYNAMICALLY_SIZED
到ssSetNum
宏。如果s函数延迟指定的功向量的长度X
工作mdlInitializeSizes
,它必须提供一个mdlSetWorkWidths
方法来建立功向量。
请注意
如果s函数使用mdlSetWorkWidths
, s函数中所使用的功向量必须设为DYNAMICALLY_SIZED
在mdlInitializeSizes
,即使准确的值是已知的mdlInitializeSizes
被称为。s函数所使用的尺寸在mdlSetWorkWidths
.
例如,请参见sfun_dynsize.c
.
在mdlStart
,为仅在模拟开始时初始化的工作向量赋值。使用ssGet
宏检索指向每个工作向量的指针,并使用该指针初始化工作向量值。另外,使用X
工作ssGet
为功向量的特定元素赋值。X
WorkValues
Simu金宝applink引擎调用mdlStart
方法在模拟开始时执行一次。在调用此方法之前,引擎为工作向量分配内存。请勿使用mdlStart
方法用于在模拟过程中需要重新初始化的数据,例如,在启用包含s功能的已启用子系统时需要重新初始化的数据。
在mdlInitializeConditions
,初始化任何可能需要在模拟中的某些点重新初始化的工作向量的值。引擎执行mdlInitializeConditions
在仿真的开始和任何时候一个启用的子系统包含s功能被重新启用。
在mdlOutputs
,mdlUpdate
等时,使用thessGet
宏检索指向工作向量的指针,并使用该指针访问或更新工作向量值。X
工作
写一个mdlRTW
方法以允许目标语言编译器(TLC)访问工作向量。如果s函数使用DWork向量,则不需要此步骤。中写入参数数据的信息mdlRTW
方法,请参阅ssWriteRTWParamSettings
.有关使用mdlRTW
方法,请参阅用mdlRTW例程编写完全内联的s -函数(金宝app仿真软件编码器).
宏 | 描述 |
---|---|
ssSetNumRWork |
指定实际工作向量的宽度。 |
ssGetNumRWork |
查询实际工作向量的宽度。 |
ssSetNumIWork |
指定整型功向量的宽度。 |
ssGetNumIWork |
查询整数工作向量的宽度。 |
ssSetNumPWork |
指定指针工作矢量的宽度。 |
ssGetNumPWork |
查询指针工作矢量的宽度。 |
ssSetNumModes |
指定模式工作矢量的宽度。 |
ssGetNumModes |
查询模式工作矢量的宽度。 |
ssGetIWork |
获取一个指向整型功向量的指针。 |
ssGetIWorkValue |
得到整数功向量的一个元素。 |
ssGetModeVector |
得到一个指向模式功向量的指针。 |
ssGetModeVectorValue |
得到模态功向量的一个元素。 |
ssGetPWork |
得到指向指针功向量的指针。 |
ssGetPworkValue |
从指针工作向量中获取一个元素。 |
ssGetRWork |
获取浮点工作向量的指针。 |
ssGetRWorkValue |
获取浮点工作向量的一个元素。 |
ssSetIWorkValue |
设置整型功向量的一个元素的值。 |
ssSetModeVectorValue |
设置模式功向量的一个元素的值。 |
ssSetPWorkValue |
设置指针工作向量的一个元素的值。 |
ssSetRWorkValue |
设置浮点工作向量的一个元素的值。 |
下面几节提供四种基本功向量的例子。
这个例子打开一个文件并存储文件
指针在指针功向量中。
下面的语句,包含在mdlInitializeSizes
函数,指示指针工作向量包含一个元素。
ssSetNumPWork(S, 1) /*指针工作向量*/
下面的代码使用指针工作向量来存储文件
指针,从标准I/O函数返回打开外部文件
.
#define MDL_START /*修改为#undef来删除函数。*/ #if define (MDL_START) static void mdlStart(real_T *x0, SimStruct *S) {FILE *fPtr;void **PWork = ssGetPWork(S);fPtr = fopen(“文件。数据”、“r”);PWork [0] = fPtr;} #endif /* MDL_START */
下面的代码检索文件
指针从指针工作向量并传递给文件关闭
以便关闭文件。
static void mdlTerminate(SimStruct *S) {if (ssGetPWork(S) != NULL) {FILE *fPtr;fPtr = (FILE *) ssGetPWorkValue(S,0); / /指定工作值if (fPtr != NULL) {fclose(fPtr);} ssSetPWorkValue(年代,0,NULL);} }
请注意
虽然Simulink引擎处金宝app理PWork向量的释放,但是mdlTerminate
方法必须始终释放存储在PWork向量中的内存。
的功能stvctf.c
使用RWork和IWork向量对时变连续传递函数进行建模。有关这个s函数的描述,请参见示例连续状态中的不连续.
下面的示例使用模式工作矢量实现一个开关块。的mdlInitializeSizes
方法配置两个直接馈通输入端口和一个输出端口。模式向量元素指示是否从第一或第二输入端口的信号被传播到输出。s函数使用一个s函数参数和一个相应的运行时参数来存储模式值,并允许在仿真期间切换开关。
static void mdlinitializesize (SimStruct *S){/*初始化一个S函数参数来切换模式值*/ ssSetNumSFcnParams(S, 1);if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){/*返回预期的参数个数*/返回;} {int iParam = 0;int nParam = ssGetNumSFcnParams(S);for (iParam = 0;iParam < nParam;iParam++) {ssSetSFcnParamTunable(S, iParam, SS_PRM_TUNABLE);}} /*使用直接馈通初始化两个输入端口*/ if (!ssSetNumInputPorts(年代,2))返回;ssSetInputPortWidth (0, 1);ssSetInputPortWidth (1, 1); ssSetInputPortDataType( S, 0, SS_DOUBLE); ssSetInputPortDataType( S, 1, SS_DOUBLE); ssSetInputPortDirectFeedThrough( S, 0, 1); ssSetInputPortDirectFeedThrough( S, 1, 1); /* Initialize one output port */ if (!ssSetNumOutputPorts(S, 1)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortDataType( S, 0, SS_DOUBLE); /* Initialize one element in the mode vector */ ssSetNumSampleTimes(S, 1); ssSetNumModes(S,1); ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE | SS_OPTION_USE_TLC_WITH_ACCELERATOR | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | SS_OPTION_NONVOLATILE); }
的mdlInitializeConditions
方法使用s函数对话框参数的当前值初始化模式矢量值。
#define MDL_INITIALIZE_CONDITIONS /* Function: mdlinalizeconconditions ============================= * Abstract: *初始化模式向量值。*/ static void mdlinitializeconconditions (SimStruct *S) {int_T *mv = ssGetModeVector(S);real_T param = mxGetScalar(ssGetSFcnParam(S,0)); / /使用实例mv [0] = (int_T)参数;}
的mdlProcessParameters
和mdlSetWorkWidths
方法初始化并更新运行时参数。在模拟运行时,对S-function对话框参数的更改被映射到运行时参数。
/ *功能:mdlSetWorkWidths ============================================= * 文摘:*设置运行时参数的数量。*/ #define MDL_SET_WORK_WIDTHS static void mdlSetWorkWidths(SimStruct *S) {ssSetNumRunTimeParams(S,1);ssRegDlgParamAsRunTimeParam(0, 0,“P1”,SS_INT16);} / *功能:mdlProcessParameters =========================================== * 文摘:*更新运行时参数。*/ #define MDL_PROCESS_PARAMETERS static void mdlprocessesparameters (SimStruct *S) {ssUpdateDlgParamAsRunTimeParam(S,0);}
的mdlOutputs
方法在每个主要时间步骤使用新的运行时参数值更新模式向量值。然后,它使用模式向量值来确定将哪个输入信号传递到输出。
static void mdlOutputs(SimStruct *S, int_T tid) {InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);InputRealPtrsType u2Ptrs = ssGetInputPortRealSignalPtrs(S,1);real_T *y = ssGetOutputPortSignal(S,0); / /输出int_T *mode = ssGetModeVector(S);real_T param = mxGetScalar(ssGetSFcnParam(S,0)); / /使用实例if (ssIsMajorTimeStep(S)){模式[0]= (int_T)参数;}如果(!模式[0]){/ *第一输入* / y [0] = (* uPtrs [0]);}如果(模式[0]){/ *第二输入* / y [0] = (* u2Ptrs [0]);} }