/* * Copyright 1990-2005 The MathWorks, Inc. * * File: simstruc.h $Revision: 1.269.4.39 $ * * Abstract: * Data structures and access methods for S-functions. * * A Simulink model is an S-function. The SimStruct contains all entry * points within the S-function (e.g. mdlOutputs) as well any data * associated with the S-function. * * This file contains details of SimStruct (Simulink data structure) * which is used to store attributes of the model such as pointers to * storage vectors. * * Multiple SimStructs are, in general, used by a model. These SimStruct's * are arranged as a "tree". The "root" SimStruct is used by * the Simulink model. There is one child SimStruct for each S-function * block with in the model. * * The SimStruct can be used in three environments: * o With MATLAB/Simulink (MATLAB_MEX_FILE) * o With Real-Time Workshop in nonreal-time (NRT) * o With Real-Time Workshop in real-time (RT) * * Defines: * One of the following must be defined. * MATLAB_MEX_FILE - Must be defined when compiling as a MEX file, * otherwise must not be defined. * NRT - Define if creating non-real-time executable * RT - Define if creating real-time executable. * * See ENVIRONMENT MACROS section below for more info. * * Defines which must be declared by the Real-Time Workshop * generated model source. * Simulink_NAME="name" * NSAMPLE_TIMES=n * * Defines for use with the Real-Time Workshop (these are configured * by the template makefile, do not add directly to make command): * MULTITASKING - Optional (use MT for a synonym). * NUMST=n - Number of sample times in the root SimStruct. * TID01EQ=1 or 0 - Optional. Only define to 1 if sample time task * id's 0 and 1 have equal rates. * ============================================================================= */ #ifndef __SIMSTRUC__ #define __SIMSTRUC__ /*===========================================================================* * BEGIN SECTION * LIST OF KEY DEFINES CONTROLLING CONDITIONAL COMPILATION * * Simstruc properties such as definitions, access methods, etc. * are conditionally compiled depending on "who" is using the simstruc * and in what mode. * * This section list all the key #define macros controlling the inclusion/ * exclusion of features, defintions, etc. * * Typically, this section only assigns a default value (such as false). * The final value is adjusted in a subsequent section. *===========================================================================*/ /*=======================================================* * MODE: SINGLE-TASKING OR MULTI-TASKING */ #define SS_MULTITASKING (0) /*=======================================================* * MODE: SIMULATION OR GENERATED CODE * * The following #defines determine whether the simstruc is used in "normal" * Simulink simulation or in Real Time Workshop generated code. * * This is designed to be a mutually exclusive set. * One and only one should be defined to be true. */ #define SS_SIM (0) #define SS_RTW (0) /*=======================================================* * MODE: WHO IS USING THE SIMSTRUC * * The following #defines determine "who" is using the simstruc. * * This is designed to be a mutually exclusive set. * One and only one should be defined to be true. */ #define SS_SFCN_LEVEL_1 (0) #define SS_SFCN_NORMAL (0) #define SS_GENERATED_S_FUNCTION (0) #define SS_SL_INTERNAL (0) #define SS_RTW_INTERNAL (0) #define SS_SHARED_MODULE (0) /*=======================================================* * MODE: GENERATED CODE IS REAL-TIME OR NON-REAL-TIME * * Both can be false, but both can't be true */ #define SS_RT (0) #define SS_NRT (0) /*=======================================================* * MODE: ENFORCE NDEBUG */ #define SS_NDEBUG (0) /*=======================================================* * MODE: ENVIRONMENT HAS STANDARD IO AVAILABLE */ #define SS_HAVESTDIO (0) /*=======================================================* * CONTEXT STORE AND RESTORE METHODS ARE AVAILABLE */ #define SS_HAVESIMULATIONCONTEXTIO (0) /*=======================================================* * MODE: TID_EQUALS_SAMPLE_TIME_INDEX - * The model will function correctly if this define is false, however if * this define is true the model's performance may be increased depending * upon whether or not the model has fast to slow rate transitions. */ #define TID_EQUALS_SAMPLE_TIME_INDEX (0) /*=======================================================* * MODE: TID01EQ == 1 */ #define SS_TID01EQ_EQUAL_ONE (0) /*===========================================================================* * END SECTION * LIST OF KEY DEFINES CONTROLLING CONDITIONAL COMPILATION *===========================================================================*/ /*=================* * Nested includes * *=================*/ #include #include #include "tmwtypes.h" #include "simstruc_types.h" #include "stdio.h" /*===========================================================================* * BEGIN SECTION * DETERMINE FINAL VALUES OF KEY DEFINES CONTROLLING CONDITIONAL COMPILATION *===========================================================================*/ /*====================================* * Model reference sim target is an RTW generated * S-Function (from the point view of Simstruct). */ # if defined(MDL_REF_SIM_TGT) # undef MATLAB_MEX_FILE # define MATLAB_MEX_FILE (1) # undef RTW_GENERATED_S_FUNCTION # define RTW_GENERATED_S_FUNCTION (1) # endif /*====================================* * Determine => MODE: SINGLE-TASKING OR MULTI-TASKING * * This must come after the inclusion of simstruc_types.h */ #if defined(MULTITASKING) # undef SS_MULTITASKING # define SS_MULTITASKING (1) #endif /*====================================* * Determine => MODE: SIMULATION OR GENERATED CODE */ #if defined(MATLAB_MEX_FILE) || defined(SL_INTERNAL) || defined(FIPXT_SHARED_MODULE) # undef SS_SIM # define SS_SIM (1) #else # undef SS_RTW # define SS_RTW (1) #endif /*====================================* * Determine => MODE: WHO IS USING THE SIMSTRUC */ #if !defined(S_FUNCTION_LEVEL) # if defined(S_FUNCTION_NAME) # define S_FUNCTION_LEVEL 1 /* Backwards compatibility old S-functions */ # else # define S_FUNCTION_LEVEL 2 # endif #endif #if S_FUNCTION_LEVEL != 1 && S_FUNCTION_LEVEL != 2 # error Invalid S_FUNCTION_LEVEL #endif #if defined(RTW_GENERATED_S_FUNCTION) /* * Used by RTW Generated S Function, ex s-fcn target. * This flag is independent of how the * s-function is built (i.e., it is a #define in the code, not a build * flag). It is true when building the s-function for use with simulink and * when building the s-function for use with RTW. */ # undef SS_GENERATED_S_FUNCTION # define SS_GENERATED_S_FUNCTION (1) #elif S_FUNCTION_LEVEL == 1 /* * Used with any LEVEL 1 s-function (user written) including: * o build for use with a normal simulation (via mex command) * o build for use with rtw (grt) */ # undef SS_SFCN_LEVEL_1 # define SS_SFCN_LEVEL_1 (1) #elif defined(S_FUNCTION_NAME) /* * Used with any s-function (user written) including: * o build for use with a normal simulation (via mex command) * o build for use with rtw (grt) */ # undef SS_SFCN_NORMAL # define SS_SFCN_NORMAL (1) #elif defined(SL_INTERNAL) || defined(RSIM_WITH_SL_SOLVER) /* * Used internally by Simulink (simulink.dll). */ # undef SS_SL_INTERNAL # define SS_SL_INTERNAL (1) #elif defined(RT) || defined(NRT) /* * Used in "root" model of generated code, but not in * non-inlined, s-functions being compiled for use with the * generated code (i.e., rt_main and model.c have access, but * sfunc.c does not). */ # undef SS_RTW_INTERNAL # define SS_RTW_INTERNAL (1) #elif defined(FIPXT_SHARED_MODULE) /* * Used in shared module (such as a dll) that needs to be able to * use some feature of the simstruc. */ /* * Currently, shared module will be treated as if they are * normal sfunctions. * # undef SS_SHARED_MODULE # define SS_SHARED_MODULE (1) */ # undef SS_SFCN_NORMAL # define SS_SFCN_NORMAL (1) #elif defined(MATLAB_MEX_FILE) /* Used in mex function that is NOT an S-Function mex */ /* * Currently, plain mex functions will be treated as if they are * normal sfunctions. * # undef SS_MEX # define SS_MEX (1) */ # undef SS_SFCN_NORMAL # define SS_SFCN_NORMAL (1) #else # error Unrecognized use. #endif /*=======================================================* * Determine => MODE: GENERATED CODE IS REAL-TIME OR NON-REAL-TIME */ #if defined(RT) # undef SS_RT # define SS_RT (1) #endif #if defined(NRT) # undef SS_NRT # define SS_NRT (1) #endif /*=======================================================* * Determine => MODE: ENFORCE NDEBUG */ #if defined(NDEBUG) # undef SS_NDEBUG # define SS_NDEBUG (1) #endif /*=======================================================* * Determine => MODE: ENVIRONMENT HAS STANDARD IO AVAILABLE */ #if defined(HAVESTDIO) # undef SS_HAVESTDIO # define SS_HAVESTDIO (1) #endif /*=======================================================* * Determine => MODE: SIMULATION CONTEXT IO AVAILABLE */ #if defined(HAVESIMULATIONCONTEXTIO) # undef SS_HAVESIMULATIONCONTEXTIO # define SS_HAVESIMULATIONCONTEXTIO (1) #endif /*=======================================================* * Determine => MODE: TID_EQUALS_SAMPLE_TIME_INDEX - */ #if SS_SL_INTERNAL # undef TID_EQUALS_SAMPLE_TIME_INDEX # define TID_EQUALS_SAMPLE_TIME_INDEX (1) #else # if defined(NUMST) && defined(NSAMPLE_TIMES) # if NUMST < NSAMPLE_TIMES # error NUMST specified incorrectly # elif NUMST == NSAMPLE_TIMES # undef TID_EQUALS_SAMPLE_TIME_INDEX # define TID_EQUALS_SAMPLE_TIME_INDEX (1) # endif # endif #endif /*=======================================================* * Determine => MODE: TID01EQ == 1 */ #if defined(TID01EQ) # if TID01EQ == 1 # undef SS_TID01EQ_EQUAL_ONE # define SS_TID01EQ_EQUAL_ONE (1) # endif #endif /*===========================================================================* * END SECTION * DETERMINE FINAL VALUES OF KEY DEFINES CONTROLLING CONDITIONAL COMPILATION *===========================================================================*/ /*===========================================================================* * BEGIN SECTION * CHECK PROPER USAGE * * Issue errors if incompatible modes have been selected *===========================================================================*/ #if (defined(RT) + defined(NRT) + defined(MATLAB_MEX_FILE) + defined(SL_INTERNAL) + defined(FIPXT_SHARED_MODULE) != 1) # error Must define one of RT, NRT, MATLAB_MEX_FILE, SL_INTERNAL, or FIPXT_SHARED_MODULE # if defined(RT) # error defined(RT) # endif # if defined(NRT) # error defined(NRT) # endif # if defined(MATLAB_MEX_FILE) # error defined(MATLAB_MEX_FILE) # endif # if defined(SL_INTERNAL) # error defined(SL_INTERNAL) # endif # if defined(FIPXT_SHARED_MODULE) # error defined(FIPXT_SHARED_MODULE) # endif #endif #if (defined(NRT) && SS_MULTITASKING) # error NRT does not support MULTITASKING #endif #if (SS_SIM && SS_MULTITASKING) # error MATLAB/Simulink does not support MULTITASKING #endif /*===========================================================================* * END SECTION * CHECK PROPER USAGE * * Issue errors if incompatible modes have been selected *===========================================================================*/ /*===========================================================================* * BEGIN SECTION * DETERMINE GROUP DEFINES * * Group defines are derived from the "KEY DEFINES" listed and determined * in previous sections. *===========================================================================*/ #if ( SS_SFCN_LEVEL_1 || SS_SFCN_NORMAL || SS_GENERATED_S_FUNCTION ) # define SS_SFCN (1) #else # define SS_SFCN (0) #endif #define SS_SFCN_FOR_SIM (0) #define SS_SFCN_FOR_RTW (0) #if SS_SFCN # if SS_SIM /* * Used for s-functions (user written or s-fcn target) that are being * compiled for use with simulink.dll (i.e., for a regular sim). Includes: * o build for use with normal simulation (via mex command) * * but does not include: * * o build for use with rtw (grt) */ # undef SS_SFCN_FOR_SIM # define SS_SFCN_FOR_SIM (1) # else # undef SS_SFCN_FOR_RTW # define SS_SFCN_FOR_RTW (1) # endif #endif /*===========================================================================* * END SECTION * DETERMINE GROUP DEFINES * * Group defines are derived from the "KEY DEFINES" listed and determined * in previous sections. *===========================================================================*/ /* * Include headers for MATLAB API function prototypes (e.g. mxGetPr) */ #if SS_SL_INTERNAL # if defined(RSIM_WITH_SL_SOLVER) /* * Run-time interface for Real-Time Workshop RSIM Full target. */ # include "rt_matrx.h" # else /* * Using within Simulink itself */ # include # include # include "matrix.h" # endif #elif SS_SFCN_FOR_SIM /* * Used in simulation by sfunction */ # include # include # include "mex.h" # if !defined(S_FUNCTION_NAME) # define _S_FUNCTION_NAME_NOT_DEFINED_BEFORE_SIMSTRUCT # endif #elif SS_SFCN_FOR_RTW /* * Used in RTW by sfunction */ # include "rt_matrx.h" /* S-function is being used with Real-Time Workshop */ #elif SS_RTW_INTERNAL /* * Run-time interface for Real-Time Workshop */ # if !defined(TYPEDEF_MX_ARRAY) # define TYPEDEF_MX_ARRAY typedef real_T mxArray; # endif #else /* * Error */ # error Unhandled case #endif /*===========================================================================* *===========================================================================* *===========================================================================* * WARNING: For maintainability: * * Conditional Compilation below this point should only depend on * KEY DEFINES * or * GROUP DEFINES * that where determined in the sections above. * * In particular, #if and #elif should only depend on the KEY DEFINES and/or * GROUP DEFINES. * * All the KEY DEFINES and GROUP DEFINES always have definitions. Therefore, * the preprocessor directives defined(), #ifdef, and #ifndef are not needed * below, and their use indicates a likely maintainability problem. The * only exception is the use of #ifndef in the standard technique for guarding * against multiple inclusion and multiple definition. *===========================================================================* *===========================================================================* *===========================================================================*/ /*===============================* * Defines for S-function blocks * *===============================*/ /* * DYNAMICALLY_SIZED - Specify for sizes entries that inherit their values * from the block that drives them. * * DYNAMICALLY_TYPED - Specify for input/output port data types that can * accept a variety of data types. * * SIMSTRUCT_VERSION - An integer which is the sizeof the SimStruct times * 10000 plus the version times 100. When updating version numbers within the * Matlab image, increment both level 1 and level 2 S-functions. Level 1 * version cannot be in range 220 to 229. This was the level 2 version in * Simulink 2.20 (R10) * * DYNAMIC_DIMENSION - Specify for input/output port dimension entries that * the port inherits its dimension from the block that drives it. */ #define ALWAYS_NEEDED (0) #define CONDITIONALLY_NEEDED (1) #define NEVER_NEEDED (2) #define ALWAYS_REFRESHED (0) #define CONDITIONALLY_REFRESHED (1) #define NEVER_REFRESHED (2) #define DYNAMICALLY_SIZED (-1) #define DYNAMICALLY_TYPED (-1) #define SIMSTRUCT_VERSION_LEVEL1 (sizeof(SimStruct)*10000 + 214) #define SIMSTRUCT_VERSION_LEVEL2 (sizeof(SimStruct)*10000 + 229) #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM #ifdef __cplusplus extern "C" { #endif extern const DimsInfo_T *DYNAMIC_DIMENSION; #ifdef __cplusplus } #endif #else #define DYNAMIC_DIMENSION NULL #endif #ifndef NUM_MAT_DIMS #define NUM_MAT_DIMS (2) #endif #if SS_SL_INTERNAL #if defined(RSIM_WITH_SL_SOLVER) # define DISABLED_VARIABLE_NEXT_TIME rtMinusInf #else # define DISABLED_VARIABLE_NEXT_TIME (utGetMinusInf()) #endif #endif #define ssSampleAndOffsetAreTriggered(st,ot) \ ((st == INHERITED_SAMPLE_TIME) && (ot == INHERITED_SAMPLE_TIME)) /* * Task ID's ordering * Continuous task * Continuous but fixed in minor step task * Discrete task 1 * ... * Discrete task N * Variable sample time task(s), offset is instance number. * * If continuous task is present then it's task ID is 0, otherwise the * first discrete task ID will be 0 if it is present, etc. * All blocks with varying sample times have same sample task period of -2, * and the offset is the instance number. * * The triggered blocks are not in the sample time table and have a task ID * of -1. */ #define TRIGGERED_TID (-1) #define CONSTANT_TID (-2) #define OVERWRITE_INPUT_ANY (-2) #define OVERWRITE_INPUT_NONE (-1) /* * ssSetNumSampleTimes(S,PORT_BASED_SAMPLE_TIMES) - Indicates that the sample * times are assigned on a per port basis. */ #if !SS_SFCN_LEVEL_1 # define PORT_BASED_SAMPLE_TIMES -1 #endif /* * Frame enum */ typedef enum { FRAME_INHERITED = -1, FRAME_NO, FRAME_YES } Frame_T; #ifndef _DIMENSION_MODE_T #define _DIMENSION_MODE_T /* * Dimensions mode * S-function ports can have the following three dimensions modes: * 1) INHERIT_DIMS_MODE * - Dimensions mode depends on settings of the connected ports; * - Ports cannot have INHERIT_DIMS_MODE after model compile; * 2) FIXED_DIMS_MODE * - Signal dimensions are fixed during simulation; * 3) VARIABLE_DIMS_MODE * - Signal dimensions are allowed to change during simulation. */ typedef enum { INHERIT_DIMS_MODE = -1, FIXED_DIMS_MODE, VARIABLE_DIMS_MODE } DimensionsMode_T; #endif typedef enum { BD_ERR_VALUE_NONE, BD_ERR_VALUE_WARNING, BD_ERR_VALUE_ERROR } BDErrorValue; /*==========================================================================* * PropagationPassType - used to distinguish for pass intialization * If you add or update PropagationPassType, update sl_types_compile.h too *==========================================================================*/ #ifndef _PROPAGATIONPASSTYPE # define _PROPAGATIONPASSTYPE typedef enum { DIMENSION_PROPAGATION, TYPE_PROPAGATION, COMPLEX_PROPAGATION } PropagationPassType; #endif /*==========================================================================* * slIdxPortType - used to determine the indexing type of a port *==========================================================================*/ typedef enum { INDEX_BASE0, INDEX_BASE1, NONINDEX } slIdxPortType; typedef enum { SIM_PAUSE, SIM_CONTINUE } ssSimStatusChangeType; /*===============================================* * General defines used only by the macros below * *===============================================*/ /* * Conversion routines for frame data storage */ #define NEG1_2BITS '\x03' #define CONV_BITS2INT(val) \ ( (((val) & 2U) != 0) ? FRAME_INHERITED : ((int)(val)) ) #define CONV_INT2BITS(val) \ ( ((val) == FRAME_INHERITED) ? (NEG1_2BITS) : ((val) & 1U) ) /* * Conversion routines for dimensions mode storage */ #define CONV_BITS2DIMSMODE(val) \ ( (((val) & 2U) != 0) ? INHERIT_DIMS_MODE : ((int)(val)) ) #define CONV_DIMSMODE2BITS(val) \ ( ((val) == INHERIT_DIMS_MODE) ? (NEG1_2BITS) : ((val) & 1U) ) /*=================================================================* * Defines used by Simulink.c when calling the S-function routines * *=================================================================*/ #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM # define SS_CALL_MDL_INITIALIZE_SAMPLE_TIMES 101 # define SS_CALL_MDL_INITIALIZE_CONDITIONS 102 # define SS_CALL_MDL_GET_TIME_OF_NEXT_VAR_HIT 103 # define SS_CALL_MDL_OUTPUTS 104 # define SS_CALL_MDL_UPDATE 105 # define SS_CALL_MDL_DERIVATIVES 106 # define SS_CALL_MDL_TERMINATE 107 # define SS_CALL_MDL_ZERO_CROSSINGS 108 # define SS_CALL_MDL_GET_INPUT_PORT_WIDTH 109 # define SS_CALL_MDL_GET_OUTPUT_PORT_WIDTH 110 # define SS_CALL_MDL_SET_WORK_WIDTHS 111 # define SS_CALL_MDL_CHECK_PARAMETERS 112 # define SS_CALL_MDL_SET_INPUT_PORT_DATA_TYPE 113 # define SS_CALL_MDL_SET_OUTPUT_PORT_DATA_TYPE 114 # define SS_CALL_MDL_SET_INPUT_PORT_WIDTH 115 # define SS_CALL_MDL_SET_OUTPUT_PORT_WIDTH 116 # define SS_CALL_MDL_START 117 # define SS_CALL_MDL_PROCESS_PARAMETERS 118 # define SS_CALL_MDL_RTW 119 # define SS_CALL_MDL_SET_INPUT_PORT_COMPLEX_SIGNAL 120 # define SS_CALL_MDL_SET_OUTPUT_PORT_COMPLEX_SIGNAL 121 # define SS_CALL_MDL_SET_INPUT_PORT_SAMPLE_TIME 122 # define SS_CALL_MDL_SET_OUTPUT_PORT_SAMPLE_TIME 123 # define SS_CALL_RTW_GENERATED_ENABLE 124 # define SS_CALL_RTW_GENERATED_DISABLE 125 # define SS_CALL_MDL_SET_INPUT_PORT_DIMENSION_INFO 126 # define SS_CALL_MDL_SET_OUTPUT_PORT_DIMENSION_INFO 127 # define SS_CALL_MDL_SET_INPUT_PORT_FRAME_DATA 128 # define SS_CALL_MDL_PROJECTION 129 # define SS_CALL_MDL_JACOBIAN 130 # define SS_CALL_MDL_SET_DEFAULT_PORT_DIMENSION_INFO 131 # define SS_CALL_MDL_SET_DEFAULT_PORT_DATA_TYPES 132 # define SS_CALL_MDL_SET_DEFAULT_PORT_COMPLEX_SIGNALS 133 # define SS_CALL_MDL_EXT_MODE_EXEC 134 # define SS_CALL_MDL_RTWCG 135 # define SS_CALL_MDL_MASSMATRIX 136 # define SS_CALL_MDL_FORCINGFUNCTION 137 # define SS_CALL_MDL_SIMULATIONCONTEXTIO 138 # define SS_CALL_MDL_ENABLE 139 # define SS_CALL_MDL_DISABLE 140 # define SS_CALL_MDL_SIM_STATUS_CHANGE 141 # define SS_CALL_MDL_INITIALIZE_PROPAGATION_PASS 142 #endif /*=================================================================* * Defines for use by External Mode during simulation * *=================================================================*/ #ifndef ExtModeLogBlockMeth_def #define ExtModeLogBlockMeth_def typedef enum { /* * Called when the user request the trigger to be armed (i.e., after * the 'arm trigger' button is pressed and the trigger arm message * has successfully been handed off to ext_comm). */ EXTLOGTASK_TRIG_ARM, /* * Called when the first point of a one-shot arrives. */ EXTLOGTASK_INIT_EVENT, /* * Definitions: * one-shot: one buffer of data collected when the trigger fires. * normal-mode: a series of one-shots * * When in normal mode, each buffer in the series, except for the last * buffer is consider to be an 'intermediate' buffer. When the final * point of an intermediate buffer has arrived on the host, the * EXTLOGTASK_TERM_INTERMEDIATE_ONESHOT method is called. When the * final point of the last buffer of the series arrives, the * EXTLOGTASK_TERM_SESSION is called. * * Note that when not in normal mode, the * EXTLOGTASK_TERM_INTERMEDIATE_ONESHOT method is never called. * * Also see EXTLOGTASK_TERM_SESSION. */ EXTLOGTASK_TERM_INTERMEDIATE_ONESHOT, /* * Called when: * o In normal mode and the last point of the last buffer in a one-shot * series has arrived (i.e., this is the end of the current log session). * * o When in one-shot mode and the final point arrives (again this is the * end of the logging session since the one and only buffer has been * acquired). * * See comments for: EXTLOGTASK_TERM_INTERMEDIATE_ONESHOT */ EXTLOGTASK_TERM_SESSION } ExtModeLogBlockMeth; #endif /*==================================* * Structures with in the SimStruct * *==================================*/ #ifndef _SIMSTRUCT # define _SIMSTRUCT /* * Use incomplete type for function prototypes within SimStruct itself */ typedef struct SimStruct_tag SimStruct; #endif #ifndef _DATA_TYPE_ACCESS #define _DATA_TYPE_ACCESS /* * Use incomplete type for function prototypes within DataTypeAccess itself */ typedef struct _slDataTypeAccess_tag slDataTypeAccess; #endif typedef struct ssSparseMatrixInfo_tag { int_T mRows; /* number of rows */ int_T nCols; /* number of cols */ int_T nzMax; /* size of *pr, *ir */ int_T *Ir; /* row indices */ int_T *Jc; /* column offsets */ real_T *Pr; /* nonzero entries */ } ssSparseMatrixInfo; typedef enum { /* What happens when a zero crossings occurs */ DISCONTINUITY_AT_ZC, CONTINUITY_AT_ZC, TRIGGERED_DISCON_AT_ZC } ZCType; /* For Backward compatibility with R12Lcs */ #define SS_UNORIENTED_OR_COL_VECT SS_1_D_OR_COL_VECT #define SS_UNORIENTED_OR_ROW_VECT SS_1_D_OR_ROW_VECT #define SS_UNORIENTED_ROW_OR_COL_VECT SS_1_D_ROW_OR_COL_VECT #define SS_UNORIENTED_VECT SS_1_D_VECT typedef enum ssVectorMode_tag{ SS_UNKNOWN_MODE, SS_1_D_OR_COL_VECT, SS_1_D_OR_ROW_VECT, SS_1_D_ROW_OR_COL_VECT, SS_1_D_VECT, SS_COL_VECT, SS_ROW_VECT } ssVectorMode; /* * _ssSizes - valid in all SimStruct's. There is one sizes for a level-1 * S-function and another sizes for a level 2 S-function. */ struct _ssSizes { int_T numContStates; /* number of continuous states */ int_T numDiscStates; /* number of discrete states */ union { int_T numOutputPorts; /* number of output ports for S-functions */ int_T numY; /* Length of the external output vector for models i.e. the sum of the widths of the outports. For level 1 S-functions, this is the output port width. */ } out; union { int_T numInputPorts; /* number of input ports for S-functions */ int_T numU; /* Length of the external input vector for models i.e. the sum of the widths of the inports. For level 1 S-functions, this is the input port width. */ } in; int_T mexApiInt1; /* reserved for use by Simulink mex api */ int_T sysDirFeedThrough; /* Not used by s-functions - only for root models */ int_T numSampleTimes; /* # of different sample times and/or time offsets*/ int_T numSFcnParams; /* number of external matrices passed in */ /* -------- Work vectors ------------------------ */ int_T numIWork; /* size of integer work vector */ int_T numRWork; /* size of real_T precision work vector */ int_T numPWork; /* size of pointer work vector */ /* -------- Block counts ------------------------ */ int_T numBlocks; /* number of Blocks in the model */ int_T numSFunctions; /* number of S-Functions */ /* -------- Model bookkeeping ------------------- */ int_T numBlockIO; /* number of block outputs */ int_T numBlockParams; /* number of block parameters */ uint32_T checksums[4]; /* Checksums of model */ /* -------- Version ----------------------------- */ int32_T simStructVer; /* SimStruct version */ /* -------- Zero Crossings ---------------------- */ int_T numNonsampledZCs; /* number of nonsampled zero crossings */ int_T numZCEvents; /* number of zero crossing events */ /* -------- Modes ------------------------------- */ int_T numModes; /* number of modes */ /* -------- Configuration options --------------- */ uint32_T options; /* General options */ /* -------- Vector Sizes In Bytes -------------- */ int_T sizeofY; /* Sizeof of external input, Y, in bytes */ int_T sizeofU; /* Sizeof of external input, U, in bytes */ int_T sizeofBlockIO; /* size of block outputs (number of bytes) */ int_T sizeofGlobalBlockIO; /* size of the global block outputs in bytes*/ int_T numDWork; /* size of data type work vectors */ int_T sizeofDWork; /* Size of data type work vector. Depends on dwork data types, complex signals, and num dworks. */ int_T RTWGeneratedSFcn; /* Flag which is set for rtw generated s-function */ /* Remove once all dstates are changed to dworks */ /* ------------- Reserved ------------------------*/ struct { unsigned int hasMdlDimensionsFcn: 1; /* uses width or dimension method*/ unsigned int usesNumPorts: 1; /* used for distinguishing between union fields in. and out. */ unsigned int vectMode: 4; /* used in set dimension methods */ unsigned int blockReduction: 1; /* used to request blk reduction */ unsigned int treatAsAtomic: 1; /* used to treat block as atomic subsystem */ unsigned int rtwcg: 1; /* supports CGIR */ unsigned int needAbsoluteTime: 1; unsigned int explicitFCSSCtrl: 1; /* used for explicit fcncall orig */ unsigned int modelRefTsInhSupLevel: 2; /* used for determining if a model * can inherit a sample time when it * is used as a block*/ unsigned int needElapseTime: 1; unsigned int hasSubFunctions: 1; unsigned int callsOutputInInit: 1; /* prevent lint warning about bit fields greater than 16 bits */ unsigned int reserved16: 16; /* remainder are reserved */ } flags; int_T numJacobianNzMax; /* number of nonzero elements in sparse Jacobian */ void *rtModel; /* rtModel pointer */ const void *constBlockIO; /* Pointer to invariant signals */ /* * The funky statements below were necessitated because we originally * had 5 reserved integer fields. In order to get a (void *) field * we need one int on certain platforms and two on others. To * overcome this, we have the definition below. * * Note that there is only ONE remaining reserved int (for alpha * anyway, there are 3 on other platforms i.e. the ones where * sizeof(int) = sizeof(void*) ) * * In order to use it, there will need to be added some appropriate * pre-processor definitions to keep from attempting to instantiate * an array of length 0. * * The problem is that on alpha sizeof(void *) = 64 and * sizeof(int) = 32 so we have: * 4 - 2*sizeof(void *)/sizeof(int) = 4 - 2*64/32 = 0 */ int reservedForFuture[5 - 2*sizeof(void *)/sizeof(int)]; }; #define SIZES_LENGTH (sizeof(struct _ssSizes)/sizeof(int_T)) /* * _ssPortInfo (S->portInfo), this is only used by level 2 S-functions. * */ typedef const void * const * InputPtrsType; typedef const real_T * const * InputRealPtrsType; typedef const real32_T * const * InputReal32PtrsType; typedef const int8_T * const * InputInt8PtrsType; typedef const uint8_T * const * InputUInt8PtrsType; typedef const int16_T * const * InputInt16PtrsType; typedef const uint16_T * const * InputUInt16PtrsType; typedef const int32_T * const * InputInt32PtrsType; typedef const uint32_T * const * InputUInt32PtrsType; typedef const boolean_T * const * InputBooleanPtrsType; typedef void * OutputVectType; #define GET_DATA_TYPE(dt) ((dt) & 0xFFFF) #define GET_COMPLEX_SIGNAL(dt) (((dt) & 0x10000) != 0) #define DTINFO(id, complexSignal) ((complexSignal)?((id) | 0x10000):(id)) #define INVALID_DTYPE_ID (-10) #define INVALID_DTYPE_SIZE (-1) #define INVALID_DTYPE_SIGNED (-1) #define INVALID_NUM_DTYPES (-1) #define INVALID_PORT_IDX (-1) enum { COMPLEX_INHERITED = -1, COMPLEX_NO, COMPLEX_YES }; /* * Enumeration of RTW storage class */ typedef enum { SS_RTW_STORAGE_INVALID = -1, SS_RTW_STORAGE_AUTO, SS_RTW_STORAGE_EXPORTED_GLOBAL, SS_RTW_STORAGE_IMPORTED_EXTERN, SS_RTW_STORAGE_IMPORTED_EXTERN_POINTER, SS_RTW_STORAGE_CUSTOM, SS_RTW_STORAGE_SIMULINK_GLOBAL, SS_RTW_STORAGE_NUM_CLASSES } ssRTWStorageType; /* * Enumeration of work vector origin flag values. */ typedef enum { SS_DWORK_ORIGINATED_AS_DWORK = 0, /* default */ SS_DWORK_ORIGINATED_AS_MODE, SS_DWORK_ORIGINATED_AS_RWORK, SS_DWORK_ORIGINATED_AS_IWORK, SS_DWORK_ORIGINATED_AS_PWORK, SS_DWORK_ORIGINATED_AS_DSTATE } ssDWorkOriginType; #define SS_NUM_DWORK_ORIGIN_TYPES 6 /* * Auxiliary DWork structure for S-Functions, one for each dwork. */ struct _ssDWorkAuxRecord { char_T *rtwIdentifier; int_T rtwStorageClass; char_T *rtwTypeQualifier; struct { unsigned int DisableBoundsChecking: 1; /* disable bounds check */ unsigned int ExtModeUpload: 1; /* upload dwork in extmode */ unsigned int rtwIdMustResolveToSignalObject: 1; /* Identifier must resolve to signal object */ unsigned int reserved13: 13; /* remainder are reserved */ unsigned int reserved16: 16; /* remainder are reserved */ } flags; int_T icRtpIdxPlus1; /* block runtime IC parameter * (if there is) mapped to * this dwork; 0 for none */ int_T unusedInts[3]; void *unusedPtrs[4]; }; #define SS_NOT_REUSABLE_AND_GLOBAL 0U /* default */ #define SS_REUSABLE_AND_LOCAL 1U #define SS_REUSABLE_AND_GLOBAL 2U #define SS_NOT_REUSABLE_AND_LOCAL 3U /* Registration returns 1 for success and 0 for failure */ typedef int_T (*_ssRegNumInputPortsFcn) (void * arg1, int_T nInputPorts); typedef int_T (*_ssRegNumOutputPortsFcn) (void * arg1, int_T nOutputPorts); typedef int_T (*_ssSetInputPortDimensionInfoFcn) (SimStruct *arg1, int_T port, const DimsInfo_T *dimsInfo); typedef int_T (*_ssSetOutputPortDimensionInfoFcn) (SimStruct *arg1, int_T port, const DimsInfo_T *dimsInfo); struct _ssPortInputs { int_T width; /* Number of elements in input port */ int_T directFeedThrough; /* Direct feedthrough for input port */ DTypeId dataTypeId; /* Data type of input port. */ CSignal_T complexSignal; /* Complex signal (-1=either, 0=no, or 1=yes)? */ union { const void *vect; InputPtrsType ptrs; } signal; /* Inputs for level 2 S-functions */ int_T connected; /* Are there signals entering the input port of the Sfcn? */ struct { unsigned int overWritable : 1; unsigned int optimOpts : 2; unsigned int frameData : 2; unsigned int contiguity : 1; unsigned int acceptExprInRTW : 1; unsigned int cinId : 2; unsigned int nonDerivPort : 1; unsigned int dimensionsMode : 2; unsigned int reserved6 : 4; unsigned int reserved16 : 16; } attributes; real_T sampleTime; /* Sample and offset time when */ real_T offsetTime; /* block specifies port based ts */ int_T *dims; /* port dimensions */ int_T bufferDstPort; int_T sampleTimeIndex; /* Sample time index when using port based sample times */ int_T numDims; /* port number of dimensions */ }; struct _ssPortOutputs { int_T width; /* Number of elements in output port */ DTypeId dataTypeId; /* Data type of outputs */ CSignal_T complexSignal; /* Complex signal (-1=either, 0=no, or 1=yes)? */ void *signalVect; /* Output signal */ int_T connected; /* Are the signals leaving the Sfcn driving other blocks? */ struct { unsigned int optimOpts : 2; unsigned int frameData : 2; unsigned int cToMergeBlk : 1; unsigned int constOutputExprInRTW : 1; unsigned int outputExprInRTW : 1; unsigned int trivialOutputExprInRTW : 1; unsigned int okToMerge : 2; unsigned int cecId : 2; unsigned int nonContPort : 1; unsigned int dimensionsMode : 2; unsigned int reserved3 : 1; unsigned int reserved16 : 16; } attributes; real_T sampleTime; /* Sample and offset time when */ real_T offsetTime; /* block specifies port based ts */ int_T *dims; /* port dimensions */ int_T sampleTimeIndex; /* Sample time index when using port based sample times */ int_T icRtpIdxPlus1; /* block runtime IC parameter (if * there is) mapped to this port; * 0 for none */ int_T numDims; /* port number of dimensions */ }; struct _ssPortInfo { _ssRegNumInputPortsFcn regNumInputPortsFcn; void *regNumInputPortsFcnArg; _ssRegNumOutputPortsFcn regNumOutputPortsFcn; void *regNumOutputPortsFcnArg; struct _ssPortInputs *inputs; /* Info for each input port of blk */ struct _ssPortOutputs *outputs; /* Info for each output port of blk */ }; #ifndef _SS_PARAM_REC # define _SS_PARAM_REC /* * Typedef for the enumeration that keeps track of the "transformed" * status of run-time parameters. */ typedef enum { /* * Your run-time parameter is not transformed if nDialogParamIndices is * one and there was no alteration of the dialog parameter */ RTPARAM_NOT_TRANSFORMED = 0, /* * Your run-time parameter is transformed if nDialogParamIndices > 1 or * there was an alteration of the dialog parameter value or data type. */ RTPARAM_TRANSFORMED = 1, /* * Your run-time parameter can be marked as 'make transformed tunable' * if nDialogParamIndices is one and you altered the dialog parameter * value or data type. If the parameter field contains a single * tunable variable, say 'k', then the transformed data type, etc. * version of k will be used in the generated code. All references to * tunable parameters that have been transformed must be done so in * the same fashion, otherwise an error will be generated. */ RTPARAM_MAKE_TRANSFORMED_TUNABLE = 2 } TransformedFlag; typedef struct ssParamRec_tag { /* * The parameter characteristics */ const char *name; /* Name of the parameter. This must point * to persistent memory. Do not set to a local * variable (static char name[32] or strings * "name" are okay) */ int_T nDimensions; /* Number of dimensions for this parameter */ int_T *dimensions; /* Array giving the dimension (sizes) of * the paramter */ DTypeId dataTypeId; /* For built-in data types, see BuiltInDTypeId * in simstruc_types.h */ boolean_T complexSignal; /* FALSE or TRUE */ /* * The data pointer. This is the data values for the run-time parameter. * Simulink needs this when creating the model.rtw file. Complex Simulink * signals are store interleaved. Likewise complex run-time parameters * must be stored interleaved. * * Note that mxArrays store the real and complex parts of complex * matrices as two separate contiguous pieces of data instead of * interleaving the real and complex parts. */ void *data; /* * The data attributes pointer is a persistent storage location where the * user can store additional information describing the data and then * recover this information later (potentially in a different function). */ const void *dataAttributes; /* * Run-time parameters to dialog parameter map. * * For proper interaction with 'tunable parameter variables' that * are set via the "Tunable Parameters Dialog", Simulink requires * information about how the run-time parameters are derived. * * It is an implicit assumption that all run-time parameters are derived * from the dialog parameters, i.e., ssGetSFcnParam(S,i). Thus each * run-time parameter is derived from a subset of the dialog parameters: * run-time_parameter = some_function(subset of dialog parameters). * In the simplest case, * run-time_parameter = a specific dialog parameter * * The following information specifies which dialog parameters are * used in deriving a specific run-time parameter. For the simplest case, * we have * nDialogParamIndices = 1; * dialogParamIndices = k; * transformed = false; * This case is important to identify because this will allow for * efficient and correct code generation of run-time parameters when they * map directly back to tunable parameter variables specified in * the 'Tunable Parameters Dialog'. */ int_T nDlgParamIndices; int_T *dlgParamIndices; /* Array of length nDialogParamIndices * indicating the dialog parameters that * are used in deriving the run-time * parameter */ TransformedFlag transformed; /* Transformed status */ boolean_T outputAsMatrix; /* Write out parameter as a vector (false) * [default] or a matrix (true) */ } ssParamRec; #endif typedef struct ssContextMemoryInfo_tag { void* base; size_t size; } ssContextMemoryInfo; typedef enum { SS_PRM_NOT_TUNABLE = 0, SS_PRM_TUNABLE, SS_PRM_SIM_ONLY_TUNABLE } ssParamTunability; /* Masks for determining the parameter attributes (see ssSfcnParams struct). */ #define SFCNPARAM_NOT_TUNABLE (1 << 0x0) #define SFCNPARAM_TUNABLE (1 << 0x1) #define SFCNPARAM_SIMONLY_TUNABLE (1 << 0x2) #define SFCNPARAM_CLEAR_TUNABLE (~(SFCNPARAM_NOT_TUNABLE | SFCNPARAM_TUNABLE |\ SFCNPARAM_SIMONLY_TUNABLE)) struct _ssSFcnParams { int_T dlgNum; /* Number of S-function parameters passed in */ mxArray **dlgParams; /* The S-function parameters */ uint_T *dlgAttribs; /* Disable parameter changes during simulation?*/ /* union preserves the memory map of the Simstruc; the size of an integer * is always less than or equal to that of a pointer */ union { int_T numRtp; void *placeholder; } numRtp; ssParamRec **rtp; }; struct _ssWork { int_T *iWork; /* integer work vector */ real_T *rWork; /* real work vector */ void **pWork; /* pointer work vector */ int_T *modeVector; /* mode work vector */ void *userData; /* User/application specific data */ union { struct _ssDWorkRecord *sfcn; void *root; } dWork; /* data type work vector */ struct _ssDWorkAuxRecord *dWorkAux; void *reservedForFuture[1]; }; /* * structure to hold info on zero-crossing signals */ typedef struct { unsigned char zcDir; ZCType zcType; boolean_T needsEvent; void *reservedPtrs[16]; int_T reserved[16]; } ssZeroCrossingInfo; /* * Input port variable dimensions information. */ struct _ssInPortVarDims { const int *portVarDims; void *reserved[8]; }; /* * Output port variable dimensions information. */ struct _ssOutPortVarDims { int *portVarDims; void *reserved[8]; }; /* * The _ssPortInfo2 structure is used by S-function blocks to store port * variable dimensions information */ struct _ssPortInfo2 { struct _ssInPortVarDims *inputs; struct _ssOutPortVarDims *outputs; void *reserved[8]; }; /* * The _ssBlkInfo structure can by used by S-function blocks to determine * status about the model in which they reside. */ struct _ssBlkInfo2 { void *rtwSfcnInfo; /* Used only in RTW by the S-function */ ssZeroCrossingInfo *zeroCrossingInfo; struct _ssPortInfo2 *portInfo2; void *reservedPtrs[14]; int_T reserved[16]; }; struct _ssBlkInfo { int_T inputConnected; /* Is input connected to a nonvirtual block? */ int_T outputConnected; /* Is output connected to a nonvirtual block?*/ const char_T *placementGroup; /* Name of group to place block in. Only applies to sources and sinks. Blocks with same group name will appear adjacent in the sorted list. */ void *block; /* The owner slBlock * of the s-function */ struct _ssBlkInfo2 *blkInfo2; /* More block info */ int_T absTolOffset; /* Offset from the root SimStruct absTol */ int_T reservedForFutureInt; }; /*==================================================================* * Mode of simulation - single vs multitaking. Note, variable * * step solvers ignore this property and are always singletasking * *==================================================================*/ typedef enum { GEN_FCN_SET_NUM_RUN_TIME_PARAMS, GEN_FCN_REG_RUN_TIME_PARAM, GEN_FCN_UPDATE_RUN_TIME_PARAM, GEN_FCN_REG_ALL_TUNE_PRM_AS_RTP, GEN_FCN_UPDATE_ALL_TUNE_PRM_AS_RTP, GENFCNFIXPT_DIMS_SUM_IN, GENFCNFIXPT_DIMS_SUM_OUT, GENFCNFIXPT_DIMS_SUM_DEFAULT, GENFCNFIXPT_DIMS_PROD_IN, GENFCNFIXPT_DIMS_PROD_OUT, GENFCNFIXPT_DIMS_PROD_DEFAULT, GENFCNFIXPT_DIMS_MPSWITCH_IN, GENFCNFIXPT_DIMS_MPSWITCH_OUT, GENFCNFIXPT_DIMS_LOGIC_IN, GENFCNFIXPT_DIMS_LOGIC_OUT, GENFCNFIXPT_DIMS_LOGIC_DEFAULT, GENFCNFIXPT_DIMS_GAIN_IN, GENFCNFIXPT_DIMS_GAIN_OUT, GENFCNFIXPT_DIMS_GAIN_DEFAULT, GENFCNFIXPT_LICENSE, GEN_FCN_IS_RTPARAM_TUNABLE, GEN_FCN_GET_BLOCK_HANDLE, GEN_FCN_REGISTER_DATA_STORE_FROM_NAME, GEN_FCN_READ_FROM_DATA_STORE, GEN_FCN_WRITE_TO_DATA_STORE, GEN_FCN_REGISTER_NUM_DATA_STORE, GEN_FCN_COMPUTE_INPUT, GEN_FCN_GET_DATATYPEOVERRIDE, GEN_FCN_GET_MINMAXLOG, GEN_FCN_GET_MINMAXARCHIVE, GEN_FCN_REG_CONST_RUN_TIME_PARAM, GEN_FCN_SF_INLINABLE, GEN_FCN_REG_AND_CNV_RUN_TIME_PARAM, GEN_FCN_UPDATE_AND_CNV_RUN_TIME_PARAM, GEN_FCN_SET_ZERO_BASED_IN_PORT, GEN_FCN_SET_ZERO_BASED_OUT_PORT, GEN_FCN_SET_ONE_BASED_IN_PORT, GEN_FCN_SET_ONE_BASED_OUT_PORT, GEN_FCN_SET_MODELREF_FILE_NAME, GEN_FCN_CHK_MODELREF_SOLVER_MODE, GEN_FCN_REGISTER_TYPE_FROM_NAMED_OBJECT, GEN_FCN_REGISTER_TYPE_FROM_PARAMETER, GEN_FCN_SET_MODELREF_STORAGE_CLASSES, GEN_FCN_SET_MODELREF_STORAGE_TYPE_QUALIFIERS, GEN_FCN_SET_MODELREF_IDENTIFIERS, GEN_FCN_SET_MODELREF_TEST_POINTS, GEN_FCN_CREATE_RUN_TIME_PARAM_FROM_DATA, GEN_FCN_UPDATE_RUN_TIME_PARAM_FROM_DATA, GEN_FCN_FULL_REG_AND_CNV_RUN_TIME_PARAM, GEN_FCN_SET_NUM_MODELREF_INTFPARAM_ARGS, GEN_FCN_REG_MODELREF_INTFPARAM_ARG, GEN_FCN_GET_MODELREF_INTFPARAM_ARG_DATA, GEN_FCN_SET_DATA_ALIGNMENT, GEN_FCN_SET_ASYNC_TIMER_ATTRIBUTES, GEN_FCN_SET_ASYNC_TASK_PRIORITIES, GEN_FCN_SET_NUM_MODELREF_INTFPARAM_GLOBALS, GEN_FCN_REG_MODELREF_INTFPARAM_GLOBAL, GEN_FCN_GET_MODELREF_INTFPARAM_GLOBAL_DATA, GEN_FCN_GET_ELAPSE_TIME, GEN_FCN_GET_ELAPSE_TIME_COUNTER_DTYPE, GEN_FCN_GET_ELAPSE_TIME_COUNTER, GEN_FCN_GET_ELAPSE_TIME_RESOLUTION, GEN_FCN_COMPUTE_OUTPUT, GEN_FCN_SET_OUTPUT_OVERWRITE_INPUT_IDX, GEN_FCN_SET_MODELMAPPINGINFO, GEN_FCN_SET_SF_INIT_OUTPUT, GEN_FCN_GET_PRODHWDEVICEINFO, GEN_FCN_CHK_MODELREF_SOLVER_TYPE, GEN_FCN_CHK_MODELREF_SOLVER_NAME, GEN_FCN_CHK_MODELREF_FIXED_STEP, GEN_FCN_CHK_MODELREF_START_TIME, GEN_FCN_CHK_MODELREF_STOP_TIME, GEN_FCN_REG_MODELREF_MDL_INFO, GEN_FCN_SET_MODELREF_TO_FILES, GEN_FCN_SET_MODELREF_FROM_FILES, GEN_FCN_REG_MODELREF_CHILD_MODEL, GEN_FCN_SET_BUS_PROPAGATION, GEN_FCN_SET_BUS_SOURCE_PORT, GEN_FCN_SET_BUS_INPORTS, GEN_FCN_GET_PARAM_NAME, GEN_FCN_SET_BUS_OUTPUT_OBJECT_NAME, GEN_FCN_SET_BUS_OUTPUT_AS_STRUCT, GEN_FCN_SET_NONITERATOR_ASSIGNMENT_BLOCK, GEN_FCN_COMPUTE_STATEFLOW_SYMBOL_NAME, GEN_FCN_SET_OPTIMIZE_MODELREF_INIT_CODE, GEN_FCN_REG_MDL_INFO, GEN_FCN_SET_BUS_INPUT_AS_STRUCT, GEN_FCN_NEEDS_LOCAL_ABSOLUTE_TIME, GEN_FCN_SET_TIME_SOURCE, GEN_FCN_SET_MODELREF_PORT_RESOLVED_TO_SIGNAL_OBJECTS, GEN_FCN_CHK_MODELREF_HARDWARE_SETTINGS, GEN_FCN_CHK_MODELREF_LIFE_SPAN, GEN_FCN_ENABLE_FCN_IS_TRIVIAL, GEN_FCN_DISABLE_FCN_IS_TRIVIAL, GEN_FCN_SET_ASYNC_TIMER_DATA_TYPE, GEN_FCN_GET_CONTEXT_SYS_PTR, GEN_FCN_GET_CONTEXT_TID, GEN_FCN_SET_OUTPUT_FCN_CALLED_MULTIPLE, GEN_FCN_SET_NOT_MULTIPLE_INLINEABLE, GEN_FCN_GET_DATA_STORE_ADDR, GEN_FCN_REGISTER_TYPE_FROM_EXPR, GEN_FCN_REGISTER_TYPE_FROM_EXPR_NO_ERROR, GEN_FCN_SET_NUM_ZCSIGNALS, GEN_FCN_REG_MODELREF_NONCONTSIGS, GEN_FCN_CHK_MODELREF_VSOLVER_OPTS, GEN_FCN_SET_INPUTS_NEED_ADDRESS, GEN_FCN_SET_INPUT_DIMS_MODE, GEN_FCN_SET_OUTPUT_DIMS_MODE, GEN_FCN_REG_SET_INPUT_DIMS_MODE_MTH, GEN_FCN_READ_FROM_DATA_STORE_ELEM, GEN_FCN_WRITE_TO_DATA_STORE_ELEM, GEN_FCN_GET_DATA_STORE_INFO, GEN_FCN_MODELREF_SET_FUNDAMENTAL_SAMPLE_TIME_INFO } GenFcnType; #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM /* following return 1 on success and 0 on failure */ typedef int_T (*_WriteRTWStrFcn)( void *writeRTWFcnArg, const char_T *str); typedef int_T (*_WriteRTWNameValuePairFcn)( void *writeRTWFcnArg, int_T type, const char_T *name, const void *value, DTypeId dataTypeId, int_T nRows, int_T nCols); typedef int_T (*_WriteRTWParameterFcn)( void *writeRTWFcnArg, int_T type, const char_T *name, const char_T *str, const void *value, DTypeId dataTypeId, int_T nRows, int_T nCols); typedef void (*_AccelRunBlockFcn)( SimStruct *S, int sysidx, int blkidx, int enumFunction); typedef int_T (*_GenericFcn) ( SimStruct *S, GenFcnType type, int_T arg1, void *arg2); #endif #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM /* * The following return error string on failure, NULL on success. * See /simulink/src/barplot.c for an example of using * these functions. */ /* * Returns an array of output port pointers corresponding to the selected * signals in the window that the s-function block resides (i.e., the signals * whose lines have selection handles). There are two options that can * be passed to this function (sigSetOpt): * SIGSET_GRAPH: return only the selected signals in the window in * which the s-function resides. * SIGSET_GRAPH_N_CHILDREN: return selected signals in the window in * which the s-function resides and all * children windows. */ typedef const char *(*SelectedSignalsFcn)( const void *voidBlock, const int sigSetOpt, void ***voidOutPortObjs, /* the ports */ int *outnPortObjs); /* the number of ports */ /* * Given an array of output ports, create a signal list so that the signal * data may be accessed (also see sigmapdef.h). Return an error string on * failure or NULL on success. */ typedef const char *(*SigListCreateFcn)( const void *voidBlock, const int nPorts, void **voidPortObjs, const unsigned int excludeFlags, void **voidOutSigList); /* * Destroy a signal list. */ typedef void (*SigListDestroyFcn)(void *voidSigList); /* * Access into Simulink memory manager's free function. Used to destroy * objects that were created by calling into Simulink (e.g., ssCall..). This * function is accessed via the ssCallGenericDestroyFcn macro. */ typedef void (*utFreeFcn)(void *ptr); /* * Given a pointer to a port, return it's name (signal label). */ typedef const char *(*GetPortNameFcn)(void *voidPortObj); /* * Given a signal list, detect and alert users to any signals that * are not available for viewing. */ typedef void (*SigListUnavailSigAlertFcn)(void *voidSigList); /* * Given a port, unselect it's line. */ typedef void (*UnselectSigFcn)(void *voidPortObj); /* * Given a SigList return .... */ /* number of regions comprising the 'listIdx-th' signal in the list */ typedef int (*SigListGetNumRegionsFcn)(void *voidSigList, int idx); /* a pointer to the first region of the 'listIdx-th'signal in the list */ typedef void* (*SigListGetFirstRegFcn)(void *voidSigList, int idx); /* the total num of elements comprising the 'listIdx-th' signal in the list */ typedef int (*SigListGetNumElementsFcn)(void *voidSigList, int idx); /* true if the signal is a tie wrap (see sigmapdef.h) */ typedef int (*SigListGetIfTieWrapFcn)(void *voidSigList, int idx); typedef struct _SignalAccess_tag { SelectedSignalsFcn SelectedSignals; SigListCreateFcn SigListCreate; SigListDestroyFcn SigListDestroy; SigListUnavailSigAlertFcn SigListUnavailSigAlert; SigListGetNumRegionsFcn SigListGetNumRegions; SigListGetFirstRegFcn SigListGetFirstReg; SigListGetNumElementsFcn SigListGetNumElements; SigListGetIfTieWrapFcn SigListGetIfTieWrap; utFreeFcn utFree; GetPortNameFcn GetPortName; UnselectSigFcn UnselectSig; } SignalAccess; #endif typedef enum { GEN_DTA_INT_PROP_SIZE, GEN_DTA_INT_PROP_STORAGE_ID, GEN_DTA_INT_PROP_ID_ALIASED_THRU_TO, GEN_DTA_INT_PROP_PROPERTIES_SIZE, GEN_DTA_INT_PROP_ID_ALIASED_TO, GEN_DTA_INT_PROP_NUM_ELEMENTS } GenDTAIntPropType; typedef enum { GEN_DTA_INT_PROP_ELEMENT_DATA_TYPE, GEN_DTA_INT_PROP_ELEMENT_SIGNAL_TYPE, GEN_DTA_INT_PROP_ELEMENT_NUM_DIMENSIONS, GEN_DTA_INT_PROP_ELEMENT_OFFSET } GenDTAIntElemPropType; typedef enum { GEN_DTA_VOID_PROP_NAME, GEN_DTA_VOID_PROP_ZERO, GEN_DTA_VOID_PROP_PROPERTIES, GEN_DTA_VOID_PROP_OBJECT } GenDTAVoidPropType; typedef enum { GEN_DTA_VOID_PROP_ELEMENT_NAME, GEN_DTA_VOID_PROP_ELEMENT_DIMENSIONS } GenDTAVoidElemPropType; typedef enum { GEN_DTA_UNARY_FCN_IS_POSITIVE, GEN_DTA_UNARY_FCN_IS_NEGATIVE } GenDTAUnaryFcnType; typedef enum { GEN_DTA_BINARY_FCN_GREATER_THAN, GEN_DTA_BINARY_FCN_GREATER_EQUAL } GenDTABinaryFcnType; typedef enum { GEN_DTA_DATA_OVERFLOW, GEN_DTA_INT32_TO_FLOAT, GEN_DTA_PARAMETER_OVERFLOW, GEN_DTA_PARAMETER_PRECISION_LOSS, GEN_DTA_PARAMETER_DOWNCAST, GEN_DTA_PARAMETER_UNDERFLOW } GenDTADiagnosticType; typedef struct slErrMsg_tag* (*RegisterDataTypeWithCheck) (void *, const char_T *, const char_T *, DTypeId *); typedef DTypeId (*RegisterDataType) (void *, const char_T *, const char_T *); typedef int_T (*GetNumDataTypes) (void *); typedef DTypeId (*GetDataTypeId) (void *, const char_T *); typedef int_T (*GetGenericDTAIntProp) (void *, const char_T *, DTypeId, GenDTAIntPropType); typedef int_T (*SetGenericDTAIntProp) (void *, const char_T *, DTypeId, int_T, GenDTAIntPropType); typedef int_T (*GetGenericDTAIntElemProp) (void *, const char_T *, DTypeId, int_T, GenDTAIntElemPropType); typedef int_T (*SetGenericDTAIntElemProp) (void *, const char_T *, DTypeId, int_T, int_T, GenDTAIntElemPropType); typedef const void* (*GetGenericDTAVoidProp) (void *, const char_T *, DTypeId, GenDTAVoidPropType); typedef int_T (*SetGenericDTAVoidProp) (void *, const char_T *, DTypeId, const void *, GenDTAVoidPropType); typedef const void* (*GetGenericDTAVoidElemProp) (void *, const char_T *, DTypeId, int_T, GenDTAVoidElemPropType); typedef int_T (*SetGenericDTAVoidElemProp) (void *, const char_T *, DTypeId, int_T, const void *, GenDTAVoidElemPropType); typedef int_T (*ConvertBetweenFcn) (slDataTypeAccess *, const char_T *, DTypeId, DTypeId, int_T, const void *, const void *, void *); typedef ConvertBetweenFcn (*GetConvertBetweenFcn) (void *, const char_T *, DTypeId); typedef int_T (*SetConvertBetweenFcn) (void *, const char_T *, DTypeId, ConvertBetweenFcn); typedef int_T (*GenericDTAUnaryFcn) (slDataTypeAccess *, const char_T *, DTypeId, int_T, const void *, const void *, void *); typedef GenericDTAUnaryFcn (*GetGenericDTAUnaryFcnGW) (void *, const char_T *, DTypeId, GenDTAUnaryFcnType); typedef int_T (*SetGenericDTAUnaryFcnGW) (void *, const char_T *, DTypeId, GenericDTAUnaryFcn, GenDTAUnaryFcnType); typedef int_T (*GenericDTAUnaryFcnGW) (slDataTypeAccess *, DTypeId, int_T, const void *, const void *, void *, GenDTAUnaryFcnType); typedef int_T (*GenericDTABinaryFcn) (slDataTypeAccess *, const char_T *, DTypeId, int_T, const void *, const void *, const void *, void *); typedef GenericDTABinaryFcn (*GetGenericDTABinaryFcnGW) (void *, const char_T *, DTypeId, GenDTABinaryFcnType); typedef int_T (*SetGenericDTABinaryFcnGW) (void *, const char_T *, DTypeId, GenericDTABinaryFcn, GenDTABinaryFcnType); typedef int_T (*GenericDTABinaryFcnGW) (slDataTypeAccess *, DTypeId, int_T, const void *, const void *, const void *, void *, GenDTABinaryFcnType); typedef int_T (*GetGenericDTADiagnostic) (void *, const char_T *, GenDTADiagnosticType, BDErrorValue *); struct _slDataTypeAccess_tag { void *dataTypeTable; const char_T *errorString; RegisterDataType registerFcn; GetNumDataTypes getNumDataTypesFcn; GetDataTypeId getIdFcn; GetGenericDTAIntProp getGenericDTAIntProp; SetGenericDTAIntProp setGenericDTAIntProp; GetGenericDTAVoidProp getGenericDTAVoidProp; SetGenericDTAVoidProp setGenericDTAVoidProp; GetGenericDTAUnaryFcnGW getGenericDTAUnaryFcnGW; SetGenericDTAUnaryFcnGW setGenericDTAUnaryFcnGW; GetGenericDTABinaryFcnGW getGenericDTABinaryFcnGW; SetGenericDTABinaryFcnGW setGenericDTABinaryFcnGW; GetConvertBetweenFcn getConvertBetweenFcn; SetConvertBetweenFcn setConvertBetweenFcn; GetGenericDTADiagnostic getGenericDTADiagnostic; RegisterDataTypeWithCheck registerFcnWithCheck; GetGenericDTAIntElemProp getGenericDTAIntElemProp; SetGenericDTAIntElemProp setGenericDTAIntElemProp; GetGenericDTAVoidElemProp getGenericDTAVoidElemProp; SetGenericDTAVoidElemProp setGenericDTAVoidElemProp; }; /* * Call into the s-functions external mode fcn - if it exists. Returns * error string on failure, NULL on success. */ typedef const char *(*SFunExtModeFcn)(SimStruct *S, const ExtModeLogBlockMeth); /* * Non-continuous (sample time != 0) signals driving derivative ports * (eg. integrand input port of an integrator block) need to be tracked * in order to determine when to reset variable step solvers. */ typedef struct { int sizeInBytes; char *pCurrVal; char *pPrevVal; } ssNonContDerivSigInfo; #if defined(RTW_GENERATED_S_FUNCTION) || SS_SL_INTERNAL typedef struct ssNonContDerivSigFeedingOutports_tag { int sizeInBytes; char *currVal; struct ssNonContDerivSigFeedingOutports_tag *next; } ssNonContDerivSigFeedingOutports; #endif /* * The _ssMdlInfo structure is "valid" in the root SimStruct only. All child * SimStruct's point to the root SimStruct mdlInfo field. Care must be taken * to use the correct mapping of tid's when accessing some of mdlInfo fields * (e.g. t, sample hits, sample times, etc). from child SimStruct's (use macros * below). */ struct _ssMdlInfo { SS_SimMode simMode; /* This field indicates whether or not we are running a simulation or generating the model.rtw file */ time_T *t; /* The current time for each task. This is of dimension sizes.numSampleTimes */ int_T *sampleHits; /* sample hits - does tid have a hit? This is of dimension sizes.numSampleTimes */ time_T tStart; /* Model execution start time */ time_T tFinal; /* Final model execution stop time */ time_T timeOfLastOutput;/* Time of last model "output" */ time_T minStepSize; /* variable stepsize is always >= minStepSize */ void *timingData; /* Data used by execution or simulation engine*/ SimTimeStep simTimeStep; /* Simulation time step "mode" */ int_T stopRequested; /* True if a "stop" has been requested */ int_T logOutput; /* Log output? */ time_T *outputTimes; /* Times at which to log data */ int_T outputTimesIndex;/* Where we are in the OutputTimes vector */ int_T numOutputTimes; /* Length of OutputTimes */ int_T outputTimesOnly; /* Save [t,x,y] & continuous blocks at specified times only? */ int_T obsoletedNeedOutputAtTPlusTol; const char_T *solverName; /* Name of solver/integration alogrithm */ int_T variableStepSolver;/* true=variable or false=fixed step solver */ void *solverData; /* Work area for solver */ time_T solverStopTime; /* Solver stop time */ time_T stepSize; /* The integration step size */ int_T solverNeedsReset;/* Do we need to reset the integrator? */ struct { unsigned int zcCacheNeedsReset : 1; /* recompute zc value left? */ unsigned int derivCacheNeedsReset : 1; /* recompute derivatives? */ unsigned int blkStateChange : 1; /* did blk state change? */ unsigned int reserved1 : 1; /* was skip intg phase (<=R12) */ unsigned int forceSfcnExceptionHandling : 1; /* add exception handling * *for all S-function calls*/ unsigned int inlineParameters :1; /* is inline parameters selected * for the model? */ unsigned int solverAssertCheck :1; /* true if consistency checking is enabled and active */ unsigned int minStepViolatedError :1; /* what to do if the solver step * size is less than the min step * size: 0 => warn 1 => error */ unsigned int reserved8 :8; /* remainder are reserved */ unsigned int reserved16 :16; /* remainder are reserved */ } mdlFlags; int_T maxNumMinSteps; /* Max number of steps taken at minimum */ int_T solverRefineFactor; /* state & output refinement factor */ real_T solverRelTol; /* Integration relative tolerance */ real_T *solverAbsTol; /* abs tol for each continuous state */ time_T maxStepSize; /* variable StepSize is always <= MaxStepSize */ int_T solverMaxOrder; /* Maximum order for ode15s */ time_T fixedStepSize; /* Step size for fixed-step integrators */ int_T numNonContDerivSigInfos; ssNonContDerivSigInfo* nonContDerivSigInfos; boolean_T* solverAutoAbsTol; rtTimingBridge* timingBridge; RTWLogInfo *rtwLogInfo; /* Logging data structure for RTW */ ssSolverInfo *solverInfo; /* Solver information */ void *unused[2]; void *mexApiVoidPtr1; /* reserved for use by Simulink mex api */ int_T solverExtrapolationOrder; /* Extrapolation order for ODE14x */ int_T solverNumberNewtonIterations; /* Number of iterations for ODE14x */ /* * External mode object */ RTWExtModeInfo *extModeInfo; /* Base addresses of Block Outputs vector for the whole model */ void *blockIO; /* block inputs/outputs */ int *blockIOVarDims; /* block I/O variable dims */ /* Parameter vectors for use with Real-Time Workshop */ real_T *defaultParam; /* Default parameter vector. */ /* Note: DefaultParam points to global storage; * common to all instances of this model. * Used only by Accelerator to point to model * wide info. */ const void *mappingInfo; /* Used by RTW for providing external access to the parameters, block I/O, etc vectors */ #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM /* * Function pointers used in mdlRTW which write fields in the model.rtw file. */ _WriteRTWStrFcn writeRTWStrFcn; _WriteRTWNameValuePairFcn writeRTWNameValuePairFcn; _WriteRTWParameterFcn writeRTWParameterFcn; void *writeRTWFcnArg; _AccelRunBlockFcn accelRunBlock; void *bdRefPtr; _GenericFcn genericFcn; void *reservedForFutureMLFcns[1]; void *reservedForFutureMLArgs[4]; #endif int_T mexApiInt2; /* for use by Simulink mex api */ char_T reservedString[32]; /* IMPORTANT: Keep it fixed at 32 characters as it is needed for backward compatibility */ _ssSetInputPortDimensionInfoFcn regInputPortDimsInfo; _ssSetOutputPortDimensionInfoFcn regOutputPortDimsInfo; #if SS_SL_INTERNAL || SS_SFCN_FOR_SIM SignalAccess *signalAccess; slDataTypeAccess *dataTypeAccess; void *reservedForFutureVoid[2]; #endif void *reservedForXPC; # if SS_MULTITASKING || SS_SL_INTERNAL || SS_SFCN_FOR_SIM int_T *perTaskSampleHits; /* Matrix of dimension number of sample times by number of sample times giving sample hits as viewed in each task. Used by ssIsSpecialSampleHit within MEX files. */ # endif SolverMode solverMode; /* Simulation solver mode */ RTWGenMode rtwgenMode; int_T reservedForFutureInt[2]; real_T mexApiReal1; /* reserved for use by Simulink mex api */ real_T mexApiReal2; /* reserved for use by Simulink mex api */ void *reservedForFuture; real_T *varNextHitTimesList; boolean_T *tNextWasAdjusted; real_T *reservedDoubleVect[1]; }; /* end struct _ssMdlInfo */ /* returns 1 on success and 0 on failure */ typedef int_T (*SysOutputFcn) (void *, int_T, int_T); struct _ssCallSys { int_T *outputs; /* Which output elements call a system */ void **args1; /* 1st Argument(s) for system output fcn */ int_T *args2; /* 2nd Argument(s) for system output fcn */ SysOutputFcn *fcns; /* System output functions */ }; /*------------------------ (S)->states.modelMethods2->resolveCBK ------------*/ /* callback function support type * * returns 1 on success and 0 on failure */ typedef int_T (*_ResolveVarFcn)( const SimStruct *S, const char *, mxArray **); /* callback structure */ struct _ssResolveCBK { _ResolveVarFcn Resolver; /* Resolver function */ void *slBlock; /* Block context for resolver fcn */ }; /* callback access methods */ # define ssGetResolveMLVarCallbackStruct(S) \ ((ssGetModelMethods2(S))->resolveCBK) # define ssSetResolveMLVarCallbackFcn(S,val) \ (ssGetResolveMLVarCallbackStruct(S)).Resolver = (val) # define ssSetResolveMLVarCallbackContext(S,val) \ (ssGetResolveMLVarCallbackStruct(S)).slBlock = (val) # define ssResolveMLVarWithCallback(S,Var,mat) \ (((ssGetResolveMLVarCallbackStruct(S)).Resolver != NULL) ? \ (*(ssGetResolveMLVarCallbackStruct(S)).Resolver)(S, Var, mat) : \ (1)) /*---------------------------------------------------------------------------*/ typedef DTypeId (*OldRegisterDataType)(void *, char_T *); typedef int_T (*SetDataTypeSize) (void *, DTypeId, int_T ); typedef int_T (*GetDataTypeSize) (void *, DTypeId); typedef int_T (*SetDataTypeZero) (void *, DTypeId, void *); typedef const void * (*GetDataTypeZero) (void *, DTypeId); typedef const char_T * (*GetDataTypeName) (void *, DTypeId); typedef int_T (*SetNumDWork) (SimStruct *, int_T); struct _ssRegDataType { void *arg1; /* 1st Argument for Register Data Type */ OldRegisterDataType registerFcn; /* Register Data Type Function */ SetDataTypeSize setSizeFcn; /* Set Data Type Size Function */ GetDataTypeSize getSizeFcn; /* Get Data Type Size Function */ SetDataTypeZero setZeroFcn; /* Set Data Type Zero representation */ GetDataTypeZero getZeroFcn; /* Get Data Type Zero representation */ GetDataTypeName getNameFcn; /* Get Data Type Name Function */ GetDataTypeId getIdFcn; /* Get Data Type Id Function */ SetNumDWork setNumDWorkFcn; /* Set num data type work vector */ }; /* Access the model's boolean data type enabled flag */ typedef boolean_T (*StrictBooleanCheckEnabled) (void *); /* * Access to Simulink's data type conversion function. */ typedef boolean_T (*ConvertBuiltInDTypeFcn)( int nVals, /* num vals to convert (*2 if complex) */ boolean_T satOnIntOverFlow, /* sat on overflow? */ boolean_T doDiff, /* check for loss of info during conversion? */ const int dt1, /* original data type */ const void *v1, /* vals to convert */ const int dt2, /* destination data type */ void *v2); /* out: the converted values */ struct _ssStInfo { time_T *sampleTimes; /* Sampling periods in seconds */ time_T *offsetTimes; /* Task delay for discrete systems (0 <= OffsetTime < SampleTime) */ time_T tNext; /* Time of next hit for M,MEX S-functions */ int_T tNextTid; /* For M,MEX S-fcns, negative if not present */ int_T *sampleTimeTaskIDs; /* Maps local sample time index to the root SimStruct task ID (root sti) */ }; /* * Level 2 S-function methods: * * [mdlInitializePropagationPassFcn] - Optional routine. Perform any * necessary initialization before the * specified propagation pass begins. *=> mdlInitializeSizes - Initialize SimStruct sizes array * [mdlSetInputPortWidth] - Optional routine. Check and set input and * optionally other port widths. Can * only be in a C MEX S-function. * [mdlSetOutputPortWidth] - Optional routine. Check and set output * and optionally other port widths. Can * only be in a C MEX S-function. * [mdlSetInputPortFrameData] - Optional routine. Check and set input and * optionally other frame data. Can * only be in a C MEX S-function. *=> mdlInitializeSampleTimes - Initialize sample times. * [mdlSetWorkWidths] - Optional routine. Set the state, iwork, * rwork, pwork, etc sizes. Can only be in a * C MEX S-function. * * [mdlRTW] - Optional routine. Only called when * generating code to add information to the * model.rtw file which is used by the * Real-Time Workshop. * * <> * * [mdlInitializeConditions] - Initialize model parameters (usually * states). Will not be called if your * S-function does not have an intialize * conditions routine. * [mdlStart] - Optional routine. Preform actitons such * as allocating memory and attaching to pwork * elements. Can only be in a C MEX * S-function. * [mdlCheckParameters] - Optional routine. Will be called at * any time during the simulation loop when * parameters change. Can only be used in a * C MEX S-function. * [mdlExtModeExec] - Optional routine. Will be called during * external mode simulation loop to run the * C Mex S-function block. * SimulationLoop: * [mdlProcessParameters] - Optional routine. Called during * simulation after parameters have been * changed and verified to be okay by * mdlCheckParameters. The processing is * done at the "top" of the simulation loop * when it is safe to process the changed * parameters. Can only be used in a C MEX * S-function. * [mdlGetTimeOfNextVarHit] - Optional routine. If your S-function * has a variable step sample time, then * this routine will be called. * [mdlIntializeConditions] - Optional routine. Only called if your * S-function resides in an enabled * subsystem configured to reset states, * and the subsystem has just enabled. * => mdlOutputs - Major output call (usually updates * output signals). * [mdlUpdate] - Update the discrete states, etc. * [mdlDerivatives] - Compute the derivatives. * EndLoop * mdlTerminate - End of model housekeeping - free memory, * etc. */ typedef void (*mdlInitializeSizesFcn)(SimStruct *S); typedef void (*mdlInitializePropagationPassFcn)(SimStruct *S, PropagationPassType passType); typedef void (*mdlSetInputPortWidthFcn)(SimStruct *S, int_T portIdx, int_T width); typedef void (*mdlSetOutputPortWidthFcn)(SimStruct *S, int_T portIdx, int_T width); typedef int_T (*mdlGetInputPortWidthLevel1Fcn)(SimStruct *S, int_T outputWidth); typedef int_T (*mdlGetOutputPortWidthLevel1Fcn)(SimStruct *S, int_T inputWidth); typedef void (*mdlSetInputPortDimensionsFcn)(SimStruct *S, int_T portIdx, const DimsInfo_T *dimsInfo); typedef void (*mdlSetOutputPortDimensionsFcn)(SimStruct *S, int_T portIdx, const DimsInfo_T *dimsInfo); typedef void (*mdlSetDefaultPortDimensionsFcn)(SimStruct *S); typedef void (*mdlSetInputPortDataTypeFcn)(SimStruct *S, int_T portIdx, DTypeId inputPortDataType); typedef void (*mdlSetOutputPortDataTypeFcn)(SimStruct *S, int_T portIdx, DTypeId outputPortDataType); typedef void (*mdlSetDefaultPortDataTypesFcn)(SimStruct *S); typedef void (*mdlSetInputPortComplexSignalFcn)(SimStruct *S, int_T portIdx, CSignal_T iPortComplexSignal); typedef void (*mdlSetOutputPortComplexSignalFcn)(SimStruct *S, int_T portIdx, CSignal_T oPortComplexSignal); typedef void (*mdlSetDefaultPortComplexSignalsFcn)(SimStruct *S); typedef void (*mdlSetInputPortFrameDataFcn)(SimStruct *S, int_T portIdx, Frame_T iPortFrameData); typedef void (*RTWGeneratedEnableFcn)(SimStruct *S); typedef void (*RTWGeneratedDisableFcn)(SimStruct *S); typedef void (*mdlEnableFcn)(SimStruct *S); typedef void (*mdlDisableFcn)(SimStruct *S); typedef void (*mdlInitializeSampleTimesFcn)(SimStruct *S); typedef void (*mdlSetInputPortSampleTimeFcn)(SimStruct *S, int portIdx, real_T sampleTime, real_T offsetTime); typedef void (*mdlSetOutputPortSampleTimeFcn)(SimStruct *S, int portIdx, real_T sampleTime, real_T offsetTime); typedef void (*mdlSetWorkWidthsFcn)(SimStruct *S); typedef void (*mdlRTWFcn)(SimStruct *S); typedef void (*mdlInitializeConditionsFcn)(SimStruct *S); typedef void (*mdlInitializeConditionsLevel1Fcn)(real_T *x0, SimStruct *S); typedef void (*mdlStartFcn)(SimStruct *S); typedef void (*mdlCheckParametersFcn)(SimStruct *S); typedef void (*mdlProcessParametersFcn)(SimStruct *S); typedef void (*mdlExtModeExecFcn)(SimStruct *S); typedef void (*mdlGetTimeOfNextVarHitFcn)(SimStruct *S); typedef void (*mdlOutputsFcn)(SimStruct *S, int_T tid); typedef void (*mdlOutputsLevel1Fcn)(real_T *y, const real_T *x, const real_T *u, SimStruct *S, int_T tid); typedef void (*mdlUpdateFcn)(SimStruct *S, int_T tid); typedef void (*mdlUpdateLevel1Fcn)(real_T *x, const real_T *u, SimStruct *S, int_T tid); typedef void (*mdlDerivativesFcn)(SimStruct *S); typedef void (*mdlDerivativesLevel1Fcn)(real_T *dx, const real_T *x, const real_T *u, SimStruct *S, int_T tid); typedef void (*mdlJacobianFcn)(SimStruct *S); typedef void (*mdlProjectionFcn)(SimStruct *S); typedef void RTWCGInterface; typedef void (*mdlRTWCGFcn)(SimStruct *S, RTWCGInterface *iObj); typedef void (*mdlZeroCrossingsFcn)(SimStruct *S); typedef void (*mdlTerminateFcn)(SimStruct *S); typedef void (*mdlMassMatrixFcn)(SimStruct *S); typedef void (*mdlSimulationContextIOFcn)(SimStruct *S, const char io, FILE *fp); struct _ssMassMatrixInfo { ssMatrixType type; /* SS_MATRIX_***, ... */ ssSparseMatrixInfo info; /* Ir,Jc,Pr, etc. */ mdlMassMatrixFcn mdlMassMatrix; /* function evaluating the MassMatrix */ }; typedef void (*mdlForcingFunctionFcn)(SimStruct *S); typedef void (*mdlSimStatusChangeFcn)(SimStruct *S, ssSimStatusChangeType mEvent); struct _ssSFcnModelMethods { mdlInitializeSizesFcn mdlInitializeSizes; mdlGetInputPortWidthLevel1Fcn mdlGetInputPortWidthLevel1; mdlGetOutputPortWidthLevel1Fcn mdlGetOutputPortWidthLevel1; union { mdlSetInputPortWidthFcn mdlSetInputPortWidth; mdlSetInputPortDimensionsFcn mdlSetInputPortDims; } mdlSetInputPortDimensions; union{ mdlSetOutputPortWidthFcn mdlSetOutputPortWidth; mdlSetOutputPortDimensionsFcn mdlSetOutputPortDims; } mdlSetOutputPortDimensions; mdlSetInputPortDataTypeFcn mdlSetInputPortDataType; mdlSetOutputPortDataTypeFcn mdlSetOutputPortDataType; mdlInitializeSampleTimesFcn mdlInitializeSampleTimes; mdlSetInputPortSampleTimeFcn mdlSetInputPortSampleTime; mdlSetOutputPortSampleTimeFcn mdlSetOutputPortSampleTime; mdlSetWorkWidthsFcn mdlSetWorkWidths; mdlRTWFcn mdlRTW; union { mdlInitializeConditionsFcn level2; mdlInitializeConditionsLevel1Fcn level1; } mdlInitializeConditions; mdlStartFcn mdlStart; mdlCheckParametersFcn mdlCheckParameters; mdlProcessParametersFcn mdlProcessParameters; mdlGetTimeOfNextVarHitFcn mdlGetTimeOfNextVarHit; union { mdlOutputsFcn level2; mdlOutputsLevel1Fcn level1; } mdlOutputs; union { mdlUpdateFcn level2; mdlUpdateLevel1Fcn level1; } mdlUpdate; union { mdlDerivativesFcn level2; mdlDerivativesLevel1Fcn level1; } mdlDerivatives; mdlZeroCrossingsFcn mdlZeroCrossings; mdlTerminateFcn mdlTerminate; union { mdlSetInputPortComplexSignalFcn mdlSetInputPortComplexSignal; RTWGeneratedEnableFcn mdlEnable; } fcnInEnable; union { mdlSetOutputPortComplexSignalFcn mdlSetOutputPortComplexSignal; RTWGeneratedDisableFcn mdlDisable; } fcnOutDisable; }; /* _ssSFcnModelMethods */ struct _ssSFcnModelMethods2 { mdlProjectionFcn mdlProjection; mdlJacobianFcn mdlJacobian; mdlSetInputPortFrameDataFcn mdlSetInputPortFrameData; StrictBooleanCheckEnabled strictBooleanCheckEnabledFcn; /* Default dimensions, data types, and complex signals functions */ mdlSetDefaultPortDimensionsFcn mdlSetDefaultPortDimensions; mdlSetDefaultPortDataTypesFcn mdlSetDefaultPortDataTypes; mdlSetDefaultPortComplexSignalsFcn mdlSetDefaultPortComplexSignals; /* Reserved for model methods */ ConvertBuiltInDTypeFcn ConvertBuiltInDType; /* Callback for S-function to resolve a variable from MATLAB workspace * * using hierarchical scoping */ struct _ssResolveCBK resolveCBK; SFunExtModeFcn extModeLogFcn; mdlExtModeExecFcn mdlExtModeExec; mdlRTWCGFcn mdlRTWCG; struct _ssMassMatrixInfo *massMatrix; mdlSimulationContextIOFcn mdlSimulationContextIO; mdlForcingFunctionFcn mdlForcingFunction; mdlEnableFcn mdlEnable; mdlDisableFcn mdlDisable; mdlSimStatusChangeFcn mdlSimStatusChange; mdlInitializePropagationPassFcn mdlInitializePropagationPass; /* Reserved */ void *reserved[1]; /* don't use the last one - make it a ptr to methods3 */ void *doNotUseNeededForExtendingStruct; }; /* AlreadyWarned flag for blocks */ #define ssSetAlreadyWarnedFlag(S) \ (S)->states.flags.alreadyWarned = 1 #define ssGetAlreadyWarnedFlag(S) \ (S)->states.flags.alreadyWarned typedef real_T const * const * UPtrsType; struct _ssStates { union { void *vect; /* not const because of SL1.3 compat*/ UPtrsType uPtrs; } U; /* Inputs for level 1 S-functions */ void *Y; /* Output for level 1 S-functions */ real_T *contStates; /* Continuous state vector */ real_T *discStates; /* Discrete state vector */ struct { unsigned int alreadyWarned: 1; /* Flag used by a block to * determine if a warning has * already been thrown for this * block */ /* prevent lint warnings about bit fields greater than 16 bits */ unsigned int reserved15: 15; unsigned int reserved16: 16; } flags; int_T reserved2; real_T *dX; /* Derivative vector */ boolean_T *contStateDisabled; /* Entry for each cont state */ ZCSigState *prevZCSigState; /* Used for detecting zc events */ real_T *nonsampledZCs; /* Nonsampled zero crossing signals */ ZCDirection *nonsampledZCDirs; /* Nonsampled zc directions */ SparseHeader *jacobian; /* struct containing system Jacobian */ struct _ssSFcnModelMethods2 *modelMethods2; int_T reservedSize; }; /*===========* * SimStruct * *===========*/ struct SimStruct_tag { const char_T *modelName; /* Name of the Simulink model/Sfunc */ const char_T *path; /* Full "Simulink path" to this s-fcn */ SimStruct *parent; /* Parent SimStruct */ SimStruct *root; /* Root level SimStruct */ const char_T *errorStatus; /* Execution status. Setting to non-NULL during any mdlFunction will stop the simulation and the "status" message will be displayed. */ struct _ssSizes sizes; /* Sizes (returned when flag==0) */ struct _ssPortInfo portInfo; /* Input and output port properties such as width and direct feedthrough setting. */ struct _ssSFcnParams sfcnParams; /* S-function parameters passed in P1,...,Pn */ struct _ssStates states; /* Input, output, state, derivative, etc. vectors */ struct _ssWork work; /* Various work areas (rwork, iwork, pwork, user data, block I/O, block params, etc.) */ struct _ssBlkInfo blkInfo; /* Information about S-function blocks */ struct _ssMdlInfo *mdlInfo; /* Model-wide info. All children SimStruct point to root mdlInfo */ struct _ssCallSys callSys; /* For use when S-function calls a "function-call" subsystems */ struct _ssRegDataType regDataType; /* For Registering Data type */ struct _ssStInfo stInfo; /* Sample time, offset time, etc. */ struct { struct _ssSFcnModelMethods sFcn; /* For S-functions */ } modelMethods; struct SimStruct_tag **sFunctions;/* SimStruct's for S-Functions referenced via S-Function blocks. Used only with RT and NRT. */ }; /*======================================* * SimStruct Get and Set Access methods * *======================================*/ /*-------------------------------- S->modelName -----------------------------*/ /* * ModelName - This is the name of the S-function. When the SimStruct * is being used with the Real-Time Workshop, then the "root" SimStruct * model name corresponds to the name of the Simulink model. */ #define ssGetModelName(S) \ (S)->modelName /* (const char_T*) */ #define _ssSetModelName(S, name) \ (S)->modelName = (name) #if !SS_SFCN #define ssSetModelName(S,name) _ssSetModelName(S,name) #else #define ssSetModelName(S,name) ssSetModelName_cannot_be_used_in_SFunctions #endif /*-------------------------------- S->path ----------------------------------*/ /* * Path - This is the full path to the S-function. When the SimStruct * is being used with the Real-Time Workshop, then the "root" SimStruct * path corresponds to the name of the Simulink model. */ #define ssGetPath(S) \ (S)->path /* (const char_T*) */ #define _ssSetPath(S, pathPtr) \ (S)->path = (pathPtr) #if !SS_SFCN #define ssSetPath(S,pathPtr) _ssSetPath(S,pathPtr) #else #define ssSetPath(S,pathPtr) ssSetPath_cannot_be_used_in_SFunctions #endif /*-------------------------------- S->parent --------------------------------*/ /* * ParentSS - There is one SimStruct for each S-function in your model. * There is also a SimStruct for the model itself. The SimStruct's are * arranged as a tree with the model SimStruct as the root. The ParentSS * field is used to get at the model SimStruct. User written S-functions * should not use the ssGetParentSS macro directly. */ #define ssGetParentSS(S) \ (S)->parent /* (SimStruct *) */ #define _ssSetParentSS(S,parentSS) \ (S)->parent = (parentSS) #if !SS_SFCN #define ssSetParentSS(S,parentSS) _ssSetParentSS(S,parentSS) #else #define ssSetParentSS(S,parentSS) ssSetParentSS_cannot_be_used_in_SFunctions #endif /*-------------------------------- S->root ----------------------------------*/ /* * RootSS - This is the "root" SimStruct corresponding to the Simulink * model. */ #define ssGetRootSS(S) \ (S)->root /* (SimStruct *) */ #define _ssSetRootSS(S,rootSS) \ (S)->root = (rootSS) #if !SS_SFCN #define ssSetRootSS(S,rootSS) _ssSetRootSS(S,rootSS) #else #define ssSetRootSS(S,rootSS) ssSetRootSS_cannot_be_used_in_SFunctions #endif /*-------------------------------- S->errorStatus ---------------------------*/ /* ErrorStatus - For improved performance and error handling, your S-function * should do: * ssSetErrorStatus(S, "error message"); * return; * as opposed to calling mexErrMsgTxt. * * Be careful when using ssSetErrorStatus in your S-function. Sometimes you * may wish to use sprintf to format the message. In this case, you * need to allocate memory for the message as opposed to using the stack. */ #define ssGetErrorStatus(S) \ ssGetRootSS(S)->errorStatus /* (const char_T*) */ #define ssSetErrorStatus(S, string) \ ssGetRootSS(S)->errorStatus = (string) /*-------------------------------- S->sizes ---------------------------------*/ /* SizesPtr - This is an integer pointer of length SIZES_LENGTH. The * fields in the sizes pointers are defined in the _ssSizes structure * (above). */ #define ssGetSizesPtr(S) \ ((int_T *)&(S)->sizes) /* (int_T *) */ /* NumContStates - This is the number of continuous states within your * S-function. The root SimStruct contains the number of continuous states * within the model itself (including all blocks and S-functions). */ #define ssGetNumContStates(S) \ (S)->sizes.numContStates /* (int_T) */ #define ssSetNumContStates(S,nContStates) \ (S)->sizes.numContStates = (nContStates) /* NumDiscStates - This is the number of discrete states within your * S-function. The root SimStruct contains the number of discrete states * within the model itself (including all blocks and S-functions). */ #define ssGetNumDiscStates(S) \ (S)->sizes.numDiscStates /* (int_T) */ #define ssSetNumDiscStates(S,nDiscStates) \ (S)->sizes.numDiscStates = (nDiscStates) /* NumTotalStates - This is the number of continuous plus discrete states * within your S-function. The root SimStruct contains the number of * continuous plus discrete states within the model itself (including all * blocks and S-functions). */ #if SS_SFCN_LEVEL_1 || !SS_SFCN # define ssGetNumTotalStates(S) \ (ssGetNumContStates(S) + ssGetNumDiscStates(S)) /* (int_T) */ #endif /* NumOutputPorts - This is the number of the output ports of your * S-function block. */ #if !SS_SFCN_LEVEL_1 # define _ssGetNumOutputPorts(S) \ ((ssGetSfcnUsesNumPorts(S) == 1)? \ ((S)->sizes.out.numOutputPorts) : 0) /*(int_T) */ # if !SS_SL_INTERNAL # define ssGetNumOutputPorts(S) \ (S)->sizes.out.numOutputPorts /* (int_T) */ # endif # define _ssSetNumOutputPorts(S,nOutputPorts) \ (S)->sizes.out.numOutputPorts = (nOutputPorts) # if SS_SFCN_FOR_SIM # define ssSetNumOutputPorts(S,nOutputPorts) \ (*(S)->portInfo.regNumOutputPortsFcn)( \ (S)->portInfo.regNumOutputPortsFcnArg,nOutputPorts) # elif SS_SFCN_FOR_RTW /* RTW S-function block */ # define ssSetNumOutputPorts(S,nOutputPorts) \ ((_ssSetNumOutputPorts(S,nOutputPorts)) >= 0) # elif SS_SL_INTERNAL || SS_RTW_INTERNAL /* Simulink or RTW model/run-time interface code */ # define ssSetNumOutputPorts(S, nOutputPorts) \ ((_ssSetNumOutputPorts(S,nOutputPorts)) >= 0) # endif # define ssSetPortInfoForOutputs(S,ptr) \ (S)->portInfo.outputs = (ptr) # define ssGetPortInfoForOutputs(S) \ (S)->portInfo.outputs #endif /* NumInputPorts - This is the number of the input ports of your * S-function block. */ #if !SS_SFCN_LEVEL_1 # define _ssGetNumInputPorts(S) \ ((ssGetSfcnUsesNumPorts(S) == 1)? \ ((S)->sizes.in.numInputPorts) : 0) /*(int_T) */ # if !SS_SL_INTERNAL # define ssGetNumInputPorts(S) \ (S)->sizes.in.numInputPorts /* (int_T) */ # endif # define _ssSetNumInputPorts(S,nInputPorts) \ (S)->sizes.in.numInputPorts = (nInputPorts) # if SS_SFCN_FOR_SIM # define ssSetNumInputPorts(S,nInputPorts) \ (*(S)->portInfo.regNumInputPortsFcn)( \ (S)->portInfo.regNumInputPortsFcnArg,nInputPorts) # elif SS_SFCN_FOR_RTW /* RTW S-function block */ # define ssSetNumInputPorts(S,nInputPorts) \ ((_ssSetNumInputPorts(S,nInputPorts)) >= 0) # elif SS_SL_INTERNAL || SS_RTW_INTERNAL /* Simulink or RTW model/run-time interface code */ # define ssSetNumInputPorts(S, nInputPorts) \ ((_ssSetNumInputPorts(S,nInputPorts)) >= 0) # endif # define ssSetPortInfoForInputs(S,ptr) \ (S)->portInfo.inputs = (ptr) # define ssGetPortInfoForInputs(S) \ (S)->portInfo.inputs #endif #if SS_SL_INTERNAL || SS_RTW_INTERNAL /* NumY, SizeofY - This is the length of the root output * vector, Y, which is the sum of all the widths of the root outport blocks. */ # define ssGetNumY(S) \ (S)->sizes.out.numY /* (int_T) */ # define ssSetNumY(S,ny) \ (S)->sizes.out.numY = (ny) # define ssGetSizeofY(S) \ (S)->sizes.sizeofY /* (int_T) */ # define ssSetSizeofY(S,nbytes) \ (S)->sizes.sizeofY = (nbytes) /* NumU, SizeofU - This is the length of the root input * vector, U, which is the sum of all the widths of the root inport blocks. */ # define ssGetNumU(S) \ (S)->sizes.in.numU /* (int_T) */ # define ssSetNumU(S,nu) \ (S)->sizes.in.numU = (nu) # define ssGetSizeofU(S) \ (S)->sizes.sizeofU /* (int_T) */ # define ssSetSizeofU(S,nbytes) \ (S)->sizes.sizeofU = (nbytes) #endif #if SS_RTW_INTERNAL /* for backwards compatibility with RTW run-time interface */ # define ssGetNumInputs(S) ssGetNumU(S) # define ssSetNumInputs(S,nInputs) ssSetNumU(S,nInputs) # define ssGetNumOutputs(S) ssGetNumY(S) # define ssSetNumOutputs(S,nOutputs) ssSetNumY(S,nOutputs) #endif #if SS_SFCN_LEVEL_1 || SS_GENERATED_S_FUNCTION /* NumOutputs - This is the size of the output port of your S-function. */ # define ssGetNumOutputs(S) \ (S)->sizes.out.numY /* (int_T) */ # define ssSetNumOutputs(S,nOutputs) \ (S)->sizes.out.numY = (nOutputs) /* NumInputs - This is the size of the input port of your S-function. */ # define ssGetNumInputs(S) \ (S)->sizes.in.numU /* (int_T) */ # define ssSetNumInputs(S,nInputs) \ (S)->sizes.in.numU = (nInputs) #elif SS_SFCN_NORMAL # define ssGetNumOutputs(S) \ ssGetNumOutputs_cannot_be_used_in_level2_SFunctions # define ssSetNumOutputs(S) \ ssGetNumOutputs_cannot_be_used_in_level2_SFunctions # define ssGetNumInputs(S) \ ssGetNumInputs_cannot_be_used_in_level2_SFunctions # define ssSetNumInputs(S) \ ssSetNumInputs_cannot_be_used_in_level2_SFunctions #else # define ssGetNumOutputsLevel1(S) \ (S)->sizes.out.numY /* (int_T) */ # define ssSetNumOutputsLevel1(S,nOutputs) \ (S)->sizes.out.numY = (nOutputs) # define ssGetNumInputsLevel1(S) \ (S)->sizes.in.numU /* (int_T) */ # define ssSetNumInputsLevel1(S,nInputs) \ (S)->sizes.in.numU = (nInputs) #endif #define ssGetMexApiInt1(S) \ (S)->sizes.mexApiInt1 /* (int_T) */ #define ssSetMexApiInt1(S,val) \ (S)->sizes.mexApiInt1 = (val) #if !SS_SFCN_NORMAL /* DirectFeedThrough - Does your Level 1 S-function use ssGetU (i.e. u * argument)in mdlOutputs? For the root SimStruct, this field indicates * whether or not the external input vector is used when executing the * Output function (i.e. MdlOutputs) for the model. */ # define ssIsDirectFeedThrough(S) \ (S)->sizes.sysDirFeedThrough /* (int_T) */ # define ssSetDirectFeedThrough(S,dirFeed) \ (S)->sizes.sysDirFeedThrough = (dirFeed) #else # define ssIsDirectFeedThrough(S) \ ssIsDirectFeedThrough_cannot_be_used_in_level2_SFunctions # define ssSetDirectFeedThrough(S,dirFeed) \ ssSetDirectFeedThrough_cannot_be_used_in_level2_SFunctions #endif /* NumBlockIO - Number of elements in the model-wide Block IO vector. Only * valid for the root SimStruct. S-function blocks should not use this * field (i.e. set it to 0). */ #define ssGetNumBlockIO(S) \ (S)->sizes.numBlockIO /* (int_T) */ #define ssSetNumBlockIO(S,nBlockIO) \ (S)->sizes.numBlockIO = (nBlockIO) /* NumBlockParams - Number of parameter elements in the model-wide parameter * vector. Only valid for the root SimStruct. S-function blocks should not * use this field (i.e. set it to 0). */ #define ssGetNumBlockParams(S) \ (S)->sizes.numBlockParams /* (int_T) */ #define ssSetNumBlockParams(S,nBlockParams) \ (S)->sizes.numBlockParams = (nBlockParams) /* Checksum fields - The checksum fields are primarily used by the root * SimStruct to maintain consistency between Simulink external mode and * the code generated from the Real-Time Workshop. In general, user * written S-function should not use this field. */ #define ssGetChecksums(S) (S)->sizes.checksums #define ssSetChecksumVal(S,idx,val) \ (S)->sizes.checksums[idx] = (val) #define ssGetChecksumVal(S,idx) \ (S)->sizes.checksums[idx] #define ssGetChecksum0(S) \ (S)->sizes.checksums[0] /* (uint32_T) */ #define ssSetChecksum0(S,val) \ (S)->sizes.checksums[0] = (val) #define ssGetChecksum1(S) \ (S)->sizes.checksums[1] /* (uint32_T) */ #define ssSetChecksum1(S,val) \ (S)->sizes.checksums[1] = (val) #define ssGetChecksum2(S) \ (S)->sizes.checksums[2] /* (uint32_T) */ #define ssSetChecksum2(S,val) \ (S)->sizes.checksums[2] = (val) #define ssGetChecksum3(S) \ (S)->sizes.checksums[3] /* (uint32_T) */ #define ssSetChecksum3(S,val) \ (S)->sizes.checksums[3] = (val) /* RWork - This is the size of the real work vector of your S-function. * The root SimStruct contains the total number of real work elements * used within the model. */ #define ssGetNumRWork(S) \ (S)->sizes.numRWork /* (int_T) */ #define ssSetNumRWork(S,nRWork) \ (S)->sizes.numRWork = (nRWork) /* IWork - This is the size of the integer work vector of your S-function. * The root SimStruct contains the total number of integer work elements * used within the model.w */ #define ssGetNumIWork(S) \ (S)->sizes.numIWork /* (int_T) */ #define ssSetNumIWork(S,nIWork) \ (S)->sizes.numIWork = (nIWork) /* PWork - This is the size of the pointer work vector of your S-function. * The root SimStruct contains the total number of pointer work elements * used within the model. */ #define ssGetNumPWork(S) \ (S)->sizes.numPWork /* (int_T) */ #define ssSetNumPWork(S,nPWork) \ (S)->sizes.numPWork = (nPWork) /* NumSFcnParams - This is the number of expected parameters your S-function * block expects. This field is not used by the root SimStruct. */ #define ssGetNumSFcnParams(S) \ (S)->sizes.numSFcnParams /* (int_T) */ #define ssSetNumSFcnParams(S,nSFcnParams) \ (S)->sizes.numSFcnParams = (nSFcnParams) /* NumSampleTimes - This is the number of sample times your S-function has. * The root SimStruct contains the total number of sample times within * the model. */ #define ssGetNumSampleTimes(S) \ (S)->sizes.numSampleTimes /* (int_T) */ #define ssSetNumSampleTimes(S,nSampleTimes) \ (S)->sizes.numSampleTimes = (nSampleTimes) /* NumSFunctions - This field is used by the root SimStruct to keep track * of the number of child SimStruct's corresponding to S-function blocks. * This field should not be used by S-function blocks (i.e. should be 0). */ #define ssGetNumSFunctions(S) \ (S)->sizes.numSFunctions /* (int_T) */ #define ssSetNumSFunctions(S,nSFunctions) \ (S)->sizes.numSFunctions = (nSFunctions) /* NumBlocks - This field is used by the root SimStruct to keep track of * the number of nonvirtual blocks within the model. This field should * not be used by S-function blocks (i.e. should be 0). */ #define ssGetNumBlocks(S) \ (S)->sizes.numBlocks /* (int_T) */ #define ssSetNumBlocks(S,nBlocks) \ (S)->sizes.numBlocks = (nBlocks) /* Version - This field should not be used by S-function blocks directly. * The the simulink.c include file at the bottom of your S-function block * uses this field. It is also used by root SimStruct for versioning. */ #define ssGetVersion(S) \ (S)->sizes.simStructVer /* (int_T) */ #define ssSetVersion(S,ver) \ (S)->sizes.simStructVer = (ver) #define ssGetSFcnLevel(S) \ ((S)->sizes.simStructVer == SIMSTRUCT_VERSION_LEVEL2? 2: 1) /* NumNonsampledZCs - This is the number of nonsampled zero crossings your * S-function has. The root SimStruct contains the total number of nonsampled * zero crossings within your model. */ #define ssGetNumNonsampledZCs(S) \ (S)->sizes.numNonsampledZCs /* (int_T) */ #define ssSetNumNonsampledZCs(S,nNonsampledZCs) \ (S)->sizes.numNonsampledZCs = (nNonsampledZCs) /* * These must be called after ssSetNumZeroCrossingSignals */ #if defined(RTW_GENERATED_S_FUNCTION) || SS_SL_INTERNAL #define SS_NUL 0x00 #define SS_N2P 0x01 #define SS_N2Z 0x02 #define SS_Z2P 0x04 #define SS_P2N 0x08 #define SS_P2Z 0x10 #define SS_Z2N 0x20 #define SS_ALL_UP (SS_N2P | SS_N2Z | SS_Z2P) #define SS_ALL_DN (SS_P2N | SS_P2Z | SS_Z2N) #define SS_ALL (SS_ALL_UP | SS_ALL_DN) #define ssSetZeroCrossingType(S, zcIdx, val) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].zcType = (val) #define ssSetZeroCrossingDirection(S, zcIdx, val) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].zcDir = (val) #define ssSetZeroCrossingNeedsEvent(S, zcIdx, val) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].needsEvent = (val) #define ssGetZeroCrossingType(S, zcIdx) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].zcType #define ssGetZeroCrossingDirection(S, zcIdx) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].zcDir #define ssGetZeroCrossingNeedsEvent(S, zcIdx) \ (S)->blkInfo.blkInfo2->zeroCrossingInfo[(zcIdx)].needsEvent #endif /* NumZCEvents - This is the number of zero crossing events within your model. * This field is not for use by S-functions (i.e. should be 0). */ #define ssGetNumZCEvents(S) \ (S)->sizes.numZCEvents /* (int_T) */ #define ssSetNumZCEvents(S,nZCEvents) \ (S)->sizes.numZCEvents = (nZCEvents) /* * NumModes - This is the number of mode vector elements within your * S-function. In the root SimStruct, this field contains the total * number of mode vector elements within your model. */ #define ssGetNumModes(S) \ (S)->sizes.numModes /* (int_T) */ #define ssSetNumModes(S,n) \ (S)->sizes.numModes = (n) /* SizeofBlockIO - This is the size of the block I/O vector in bytes. * These should not be used by S-functions (accelerated models need to * set the size though). */ #define ssGetSizeofBlockIO(S) \ (S)->sizes.sizeofBlockIO /* (int_T) */ #define ssSetSizeofBlockIO(S,n) \ (S)->sizes.sizeofBlockIO = (n) /* SizeofGlobalBlockIO - This is the size of the global block I/O * vector in bytes. This is the size of rtB in the generated code. * These should not be used by S-functions (accelerated models need to * set the size though). */ #define ssGetSizeofGlobalBlockIO(S) \ (S)->sizes.sizeofGlobalBlockIO /* (int_T) */ #define ssSetSizeofGlobalBlockIO(S,n) \ (S)->sizes.sizeofGlobalBlockIO = (n) /* DWork - This is the number of the data type work vector of your S-function. * The root SimStruct contains the total number of data type work vectors * used within the model. */ #define ssGetNumDWork(S) \ (S)->sizes.numDWork /* (int_T) */ #define _ssSetNumDWork(S,nDWork) \ ((S)->sizes.numDWork = (nDWork)) /* SizeofDWork - This is the size of the data type work vector in bytes. * These should not be used by S-functions (accelerated models need to * set the size though). */ #define ssGetSizeofDWork(S) \ (S)->sizes.sizeofDWork /* (int_T) */ #define ssSetSizeofDWork(S,n) \ (S)->sizes.sizeofDWork = (n) /* RTWGeneratedSFcn - This is the flag which is set for rtw generated * s-function. Can be removed once all dstates are changed to dworks */ #define ssGetRTWGeneratedSFcn(S) \ (S)->sizes.RTWGeneratedSFcn /* (int_T) */ #define ssSetRTWGeneratedSFcn(S,n) \ (S)->sizes.RTWGeneratedSFcn = (n) /* HasMdlDimensionsFcn - This is the flag which is set if the block * has mdlSetInput(output)PortDimensions function. Not for use by S-functions. */ #define ssGetSfcnHasMdlDimensionsFcn(S) \ (S)->sizes.flags.hasMdlDimensionsFcn /* (unsigned int_T: 1) */ #define _ssSetSfcnHasMdlDimensionsFcn(S,n) \ (S)->sizes.flags.hasMdlDimensionsFcn = (n) /* usesNumPorts - This flag is set by ssSetNumInputPorts and * ssSetNumOutputPorts when S is used in Simulink. * Not for use by S-functions. */ #define ssGetSfcnUsesNumPorts(S) \ (S)->sizes.flags.usesNumPorts /* (unsigned int_T: 1) */ #define _ssSetSfcnUsesNumPorts(S,n) \ (S)->sizes.flags.usesNumPorts = (n) /* VectMode - This flag is used in Simulink set port dimension methods. * See ssVectorMode typedef for valid settings. */ #define ssGetVectorMode(S) \ (S)->sizes.flags.vectMode /* (unsigned int_T: 4) */ #define ssSetVectorMode(S,n) \ (S)->sizes.flags.vectMode = (n) /* BlockReduction - Specify that this block should be eliminated from the * compiled model. Note that Simulink may not honor this setting, in which * case the block will remain in the model. After blocks have been * considered for elimination, ssGetBlockReduction will return whether or * not the block was eliminated. */ #define ssGetBlockReduction(S) \ (S)->sizes.flags.blockReduction /* (unsigned int_T: 1) */ #define ssSetBlockReduction(S,n) \ (S)->sizes.flags.blockReduction = (n) /* * ss(Set|Get)TreatAsAtomic - This macro is NOT to be used by * custom S-Functions. */ #define ssGetTreatAsAtomic(S) \ (S)->sizes.flags.treatAsAtomic /* (unsigned int_T: 1) */ #define ssSetTreatAsAtomic(S,n) \ (S)->sizes.flags.treatAsAtomic = (n) /* * ss(Set|Get)HasSubFunctions - This macro is NOT to be useb by * custom S-Functions. */ #define ssGetHasSubFunctions(S) \ (S)->sizes.flags.hasSubFunctions /* (unsigned int_T: 1) */ #define ssSetHasSubFunctions(S,n) \ (S)->sizes.flags.hasSubFunctions = (n) /* * ss(Set|Get)CallsOutputInInitFcn - This macro is NOT to be useb by * custom S-Functions. */ #define ssGetCallsOutputInInitFcn(S) \ (S)->sizes.flags.callsOutputInInit /* (unsigned int_T: 1) */ #define ssSetCallsOutputInInitFcn(S,n) \ (S)->sizes.flags.callsOutputInInit = (n) /* RTWCG - Block supports CGIR code generation for RTW (instead of TLC). */ #define ssGetRTWCG(S) \ (S)->sizes.flags.rtwcg /* (unsigned int_T: 1) */ #define ssSetRTWCG(S,n) \ (S)->sizes.flags.rtwcg = (n) /* Block need absolute time. If block requiring absolute does not * set this flag. Obsolete absolute time will be used. Obsolete absolute * timer cann't support fixed pt blocks. */ #define ssGetNeedAbsoluteTime(S) \ (S)->sizes.flags.needAbsoluteTime /* (unsigned int_T: 1) */ #define ssSetNeedAbsoluteTime(S,n) \ (S)->sizes.flags.needAbsoluteTime = (n) #define ssGetNeedElapseTime(S) \ (S)->sizes.flags.needElapseTime /* (unsigned int_T: 1) */ #define ssSetNeedElapseTime(S,n) \ (S)->sizes.flags.needElapseTime = (n) /* * ss(S|G)etExplicitFCSSCtrl */ #define ssGetExplicitFCSSCtrl(S) \ (S)->sizes.flags.explicitFCSSCtrl /* (unsigned int_T: 1) */ #define ssSetExplicitFCSSCtrl(S,n) \ (S)->sizes.flags.explicitFCSSCtrl = (n) /* PortBasedSampleTimeBlockIsTriggered * This macro is for use during calls to mdlOutputs and mdlUpdate * If the first sample time is inherited at that point then the block * must be triggered (sample and offset both -1) */ #define ssGetPortBasedSampleTimeBlockIsTriggered(S) \ ((S)->stInfo.sampleTimes[0] == INHERITED_SAMPLE_TIME) /* ------------------------------- S->portInfo ------------------------------*/ /* BEGIN long level 1 exclusion */ #if !SS_SFCN_LEVEL_1 # if SS_SL_INTERNAL || SS_SFCN_FOR_SIM # define ssSetRegInputPortDimensionInfoFcn(S,fcn) \ (S)->mdlInfo->regInputPortDimsInfo = (fcn) # define ssGetRegInputPortDimensionInfoFcn(S) \ ((S)->mdlInfo->regInputPortDimsInfo) # define ssSetRegOutputPortDimensionInfoFcn(S,fcn) \ (S)->mdlInfo->regOutputPortDimsInfo = (fcn) # define ssGetRegOutputPortDimensionInfoFcn(S) \ ((S)->mdlInfo->regOutputPortDimsInfo) # endif /********************* * Input Port Width * *********************/ /* InputPortWidth - Input port width for level 2 s-functions which can * have multiple ports. Each port must have a non-zero positive width or * it can be specified as DYNAMICALLY_SIZED during the set. Latter get's * will return the resolved size for use during simulation. */ # define ssGetInputPortWidth(S,port) \ (S)->portInfo.inputs[(port)].width /* (int_T) */ # define ssSetInputPortWidth(S,port,val) \ (S)->portInfo.inputs[(port)].width = (val) /*********************************** * Input Port Number of Dimensions * ***********************************/ # define ssGetInputPortNumDimensions(S,port) \ ((S)->portInfo.inputs[(port)].numDims) /* (int_T) */ # define _ssSetInputPortNumDimensions(S,port,val) \ {\ (S)->portInfo.inputs[(port)].numDims = (val);\ if(val == 1) { \ (S)->portInfo.inputs[(port)].dims = \ &((S)->portInfo.inputs[(port)].width);\ }\ } /************************* * Input Port Dimensions * *************************/ # define ssGetInputPortDimensions(S,port) \ ((S)->portInfo.inputs[(port)].dims) /* Do not make a copy. S-function port dimension = Ptr. */ # define _ssSetInputPortDimensionsPtr(S,port,ptr) \ {\ (S)->portInfo.inputs[(port)].dims = (ptr);\ } /* * Copy 'd' to S-function port dimensions. It is assumed that * port has engough storage/memory to store the dimensions. */ # define _ssCopyInputPortDimensions(S,port,d) \ {\ int nn = ssGetInputPortNumDimensions(S,port);\ if(nn >= 1){\ (void)memcpy(ssGetInputPortDimensions(S,port),d, \ nn*sizeof(int_T)); \ }\ } /************************************************************ * Input Port Width/Number of Dimensions/Dimensions Methods * ************************************************************/ # if SS_SL_INTERNAL || SS_SFCN_FOR_SIM # define ssSetInputPortDimensionInfo(S,port,val) \ (((ssGetRegInputPortDimensionInfoFcn(S)) != NULL ) ? \ (ssGetRegInputPortDimensionInfoFcn(S))(S,port,val) : \ (1)) # else /* RTW S-function block */ # define ssSetInputPortDimensionInfo(S,port,val) (1) # endif /* Matrix dimensions */ # if SS_SL_INTERNAL || SS_SFCN_FOR_SIM # define ssSetInputPortMatrixDimensions(S,port,val1,val2) \ (_ssSetInputPortMatrixDimensions(S,port,val1,val2)) # else /* RTW S-function block */ # define ssSetInputPortMatrixDimensions(S,port,val1,val2) (1) # endif /* Vector dimensions */ # if SS_SL_INTERNAL || SS_SFCN_FOR_SIM # define ssSetInputPortVectorDimension(S,port,val) \ (_ssSetInputPortVectorDimension(S,port,val)) # else /* RTW S-function block */ # define ssSetInputPortVectorDimension(S,port,val) (1) # endif /*************************** * END of width/dimensions * ***************************/ # define ssGetInputPortSignalWhenNeeded(S,port) \ ((S)->portInfo.inputs[(port)].attributes.cinId) # define ssSetInputPortSignalWhenNeeded(S,port,val) \ (S)->portInfo.inputs[(port)].attributes.cinId = (val) # define ssGetOutputPortSignalWhenRefreshed(S,port) \ ((S)->portInfo.outputs[(port)].attributes.cecId) # define ssSetOutputPortSignalWhenRefreshed(S,port,val) \ (S)->portInfo.outputs[(port)].attributes.cecId = (val) /* InputPortFrameData - For each input port or your S-function block, this * is whether or not the incomming signal is frame data, where (-1=either, * 0=no, 1=yes). */ # define ssGetInputPortFrameData(S,port) \ CONV_BITS2INT((S)->portInfo.inputs[(port)].attributes.frameData) # define ssSetInputPortFrameData(S,port,val) \ (S)->portInfo.inputs[(port)].attributes.frameData = \ CONV_INT2BITS(val) /* InputPortDirectFeedthrough - port width for level 2 s-functions which can * have multiple ports. */ # define ssGetInputPortDirectFeedThrough(S,port) \ (S)->portInfo.inputs[(port)].directFeedThrough /* (int_T) */ # if SS_SFCN_FOR_SIM && !SS_NDEBUG #ifdef __cplusplus extern "C" { #endif extern void _ssSetInputPortDirectFeedThroughFcn(const SimStruct *S, int port, int dirFeed); #ifdef __cplusplus } #endif # define ssSetInputPortDirectFeedThrough(S,port,dirFeed) \ _ssSetInputPortDirectFeedThroughFcn(S,port,dirFeed) #else # define ssSetInputPortDirectFeedThrough(S,port,dirFeed) \ (S)->portInfo.inputs[(port)].directFeedThrough = (dirFeed) #endif /* InputDataType - For each input port of your S-function block, this is the * data type. If no data types is specified, then the default is real_T. */ # define ssGetInputPortDataType(S,port) \ (S)->portInfo.inputs[(port)].dataTypeId /* (DTypeId) */ # define ssSetInputPortDataType(S,port,dTypeId) \ ((S)->portInfo.inputs[(port)].dataTypeId = (dTypeId)) /* InputComplexSignal - For each input port or your S-function block, this is * whether or not the incomming signal is complex, where (-1=either, 0=no, * 1=yes). */ # define ssGetInputPortComplexSignal(S,port) \ (S)->portInfo.inputs[(port)].complexSignal /* (CSignal_T) */ # define ssSetInputPortComplexSignal(S,port,val) \ (S)->portInfo.inputs[(port)].complexSignal = (val) /* InputPortSignalPtrs - This is the pointers to the signal vector for each * input port. This is the default method for accessing the S-Function's * input signals. It is a *bad* error to use this macro if the S-Function * specifies ssSetInputPortRequiredContiguous as true. In that case, use * ssGetInputPortSignal(). * * The following code demonstrates the use of ssGetInputPortSignalPtrs() : * * nInputPorts = ssGetNumInputPorts(S); * for (i = 0; i < nInputPorts; i++) { * InputPtrsType u = ssGetInputPortSignalPtrs(S,i); * int_T nu = ssGetInputPortWidth(S,i); * for (j = 0; j < nu; j++) { * UseInputInSomeFunction(*u[i]); * } * } * * If you know that the input's are always real_T's signals, then the * ssGetInputPortSignalPtrs line in the above code snippet would be: * * InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,i); * */ # if SS_SFCN_FOR_SIM && !SS_NDEBUG # ifdef __cplusplus extern "C" { # endif extern InputPtrsType _ssGetInputPortSignalPtrsFcn(const SimStruct *S, int ip); # ifdef __cplusplus } # endif # define ssGetInputPortSignalPtrs(S,ip) _ssGetInputPortSignalPtrsFcn(S,ip) # define ssGetInputPortRealSignalPtrs(S,ip) \ ((InputRealPtrsType)_ssGetInputPortSignalPtrsFcn(S,ip)) # else # define ssGetInputPortSignalPtrs(S,ip) \ ( (S)->portInfo.inputs[(ip)].signal.ptrs ) /* (InputPtrsType) */ # define ssGetInputPortRealSignalPtrs(S,ip) \ ( (InputRealPtrsType) ssGetInputPortSignalPtrs(S,ip) ) # endif # define _ssSetInputPortSignalPtrs(S,ip,ptr) \ (S)->portInfo.inputs[(ip)].signal.ptrs = (ptr) # if !SS_SFCN # define ssSetInputPortSignalPtrs(S,ip,ptr) \ _ssSetInputPortSignalPtrs(S,ip,ptr) # else # define ssSetInputPortSignalPtrs(S,ip,ptr) \ ssSetInputPortSignalPtrs_cannot_be_used_in_SFunctions # endif /* InputPortSignal: This macro returns the address of the signal on the * specified input port of the S-Function. In order to use this macro for * accessing the input port signal you need to set the attribute * ssSetInputPortRequiredContiguous to true. If not, this macro returns an * invalid pointer. * * The following code demonstrates the use of ssGetInputPortSignal() : * * nInputPorts = ssGetNumInputPorts(S); * for (i = 0; i < nInputPorts; i++) { * int_T nu = ssGetInputPortWidth(S,i); * * if ( ssGetInputPortRequiredContiguous(S,i) ) { * * const void *u = ssGetInputPortSignal(S,i); * UseInputVectorInSomeFunction(u, nu); * *