Writing S-Functions | ![]() ![]() |
Specify the number of inputs, outputs, states, parameters, and other characteristics of the S-function.
Syntax
void mdlInitializeSizes(SimStruct *S)
Arguments
S
Simstruct representing an S-function block.
Description
This is the first of the S-function's callback methods that Simulink calls. This method should perform the following tasks:
Use ssSetSFcnParamNotTunable(S,paramIdx)
when a parameter cannot change during simulation, where paramIdx
starts at 0. When a parameter has been specified as "not tunable," Simulink will issue an error during simulation (or the Real-Time Workshop external mode) if an attempt is made to change the parameter.
This entails the following tasks.
SeeDynamically Sized Block Features for more information.
A port has direct feedthrough if the input is used in either the mdlOutputs or mdlGetTimeOfNextVarHit functions.The direct feedthrough flag for each input port can be set to either 1=yes
or 0=no
. It should be set to 1 if the input, u
, is used in the mdlOutput
or mdlGetTimeOfNextVarHit
routine. Setting the direct feedthrough flag to 0 tells Simulink that u
will not be used in either of these S-function routines. Violating this will lead to unpredictable results.
This entails the following tasks.
See mdlSetOutputPortDimensionInfo and ssSetOutputPortDimensionInfo for more information.
If your S-function outputs are discrete (e.g., can only take on the values, 1 and 2), then specify SS_OPTION_DISCRETE_VALUED_OUTPUT
.
There are two ways of specifying sample times:
See Sample Times for a complete discussion of sample time issues.
For multi-rate S-functions, the suggested approach to setting sample times is via the port based sample times method. When you create a multirate S-function, care needs to be taking to verify that when slower tasks are preempted that your S-function correctly manages data as to avoid race conditions. When port based sample times are specified, the block cannot inherit a constant sample time at any port.
All options have the form SS_OPTION_<name>
. See ssSetOptions for information on each option. The options should be bitwise or'd together as in
ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))
Dynamically Sized Block Features
You can set the parameters NumContStates
, NumDiscStates
, NumInputs
, NumOutputs
, NumRWork
, NumIWork
, NumPWork
, NumModes
, and NumNonsampledZCs
to a fixed nonnegative integer or tell Simulink to size them dynamically:
DYNAMICALLY_SIZED
-- Sets lengths of states, work vectors, and so on to values inherited from the driving block. It sets widths to the actual input width, according to the scalar expansion rules unless you use mdlSetWorkWidths
to set the widths.0
or positive number -- Sets lengths (or widths) to the specified value. The default is 0
. Languages
Example
static void mdlInitializeSizes(SimStruct *S) { int_T nInputPorts = 1; /* number of input ports */ int_T nOutputPorts = 1; /* number of output ports */ int_T needsInput = 1; /* direct feed through */ int_T inputPortIdx = 0; int_T outputPortIdx = 0; ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { /* * If the the number of expected input parameters is not * equal to the number of parameters entered in the * dialog box, return. Simulink will generate an error * indicating that there is aparameter mismatch. */ return; }else { mdlCheckParameters(S); if (ssGetErrorStatus(s) != NULL) return; } ssSetNumContStates( S, 0); ssSetNumDiscStates( S, 0); /* * Configure the input ports. First set the number of input * ports. */ if (!ssSetNumInputPorts(S, nInputPorts)) return; /* * Set input port dimensions for each input port index * starting at 0. */ if(!ssSetInputPortDimensionInfo(S, inputPortIdx, DYNAMIC_DIMENSION)) return; /* * Set direct feedthrough flag (1=yes, 0=no). */ ssSetInputPortDirectFeedThrough(S, inputPortIdx, needsInput); /* * Configure the output ports. First set the number of * output ports. */ if (!ssSetNumOutputPorts(S, nOutputPorts)) return; /* * Set output port dimensions for each output port index * starting at 0. */ if(!ssSetOutputPortDimensionInfo(S,outputPortIdx, DYNAMIC_DIMENSION)) return; /* * Set the number of sample times. */ ssSetNumSampleTimes(S, 1); /* * Set size of the work vectors. */ ssSetNumRWork(S, 0); /* real vector */ ssSetNumIWork(S, 0); /* integer vector */ ssSetNumPWork(S, 0); /* pointer vector */ ssSetNumModes(S, 0); /* mode vector */ ssSetNumNonsampledZCs(S, 0); /* zero crossings */ ssSetOptions(S, 0); } /* end mdlInitializeSizes */
![]() | mdlInitializeSampleTimes | mdlOutputs | ![]() |