Main Content

Use DWork Vectors in S-Functions

What is a DWork Vector?

DWork vectors are blocks of memory that an S-function asks the Simulink®engine to allocate to each instance of the S-function in a model. If multiple instances of your S-function can occur in a model, your S-function must use DWork vectors instead of global or static memory to store instance-specific values of S-function variables. Otherwise, your S-function runs the risk of one instance overwriting data needed by another instance, causing a simulation to fail or produce incorrect results.The ability to keep track of multiple instances of an S-function is calledreentrancy.

You can create an S-function that is reentrant by using DWork vectors that the engine manages for each particular instance of the S-function.

DWork vectors have several advantages:

  • Provide instance-specific storage for block variables

  • Support floating-point, integer, pointer, and general data types

  • Eliminate static and global variables

  • Interact directly with the Simulink engine to perform memory allocation, initialization, and deallocation

  • Facilitate inlining the S-function during code generation

  • Provide more control over how data appears in the generated code

Note

DWork vectors are the most generalized and versatile type of work vector and the following sections focus on their use. The Simulink product provides additional elementary types of work vectors that support floating-point, integer, pointer, and mode data. You can find a discussion of these work vectors inElementary Work Vectors.

DWork向量提供最大的灵活性,组ting data types, names, etc., of the data in the simulation and during code generation. The following list describes all the properties that you can set on a DWork vector:

  • Data type

  • 大小

  • Numeric type, either real or complex

  • Name

  • Usage type (seeTypes of DWork Vectors)

  • Simulink Coder™identifier

  • Simulink Coderstorage class

  • Simulink CoderC type qualifier

SeeHow to Use DWork Vectorsfor instructions on how to set these properties. The threeSimulink Coderproperties pertain only to code generation and have no effect during simulation.

How to use DWork Vectors in Level-2MATLABS-Functions

Using DWork Vectors in Level-2MATLABS-Functions

The following steps show how to initialize and use DWork vectors in Level-2 MATLAB®S-functions. These steps use the S-functionmsfcn_unit_delay.m.

  1. In thePostPropagationSetupmethod, initialize the number of DWork vectors and the attributes of each vector. For example, the followingPostPropagationSetupcallback method configures one DWork vector used to store a discrete state.

    function PostPropagationSetup(block) %% Setup Dwork block.NumDworks = 1; block.Dwork(1).Name = 'x0'; block.Dwork(1).Dimensions = 1; block.Dwork(1).DatatypeID = 0; block.Dwork(1).Complexity = 'Real'; block.Dwork(1).UsedAsDiscState = true;

    The reference pages forSimulink.BlockCompDworkDataand the parent classSimulink.BlockDatalist the properties you can set for Level-2 MATLAB S-function DWork vectors.

  2. Initialize the DWork vector values in either theStartorInitializeConditionsmethods. Use theStartmethod for values that are initialized only at the beginning of the simulation. Use theInitializeConditionsmethod for values that need to be reinitialized whenever a disabled subsystem containing the S-function is reenabled.

    For example, the followingInitializeConditionsmethod initializes the value of the DWork vector configured in the previous step to the value of the first S-function dialog parameter.

    function InitializeConditions(block) %% Initialize Dwork block.Dwork(1).Data = block.DialogPrm(1).Data;
  3. In theOutputs,Update, etc. methods, use or update the DWork vector values, as needed. For example, the followingOutputsmethod sets the S-function output equal to the value stored in the DWork vector. TheUpdatemethod then changes the DWork vector value to the current value of the first S-function input port.

    %% Outputs callback method function Outputs(block) block.OutputPort(1).Data = block.Dwork(1).Data; %% Update callback method function Update(block) block.Dwork(1).Data = block.InputPort(1).Data;

Note

Level-2 MATLAB S-functions do not support MATLAB sparse matrices. Therefore, you cannot assign a sparse matrix to the value of a DWork vector. For example, the following line of code produces an error

block.Dwork(1).Data = speye(10);

where thespeyecommand produces a sparse identity matrix.

Level-2MATLABS-Function DWork Vector Example

The example S-functionmsfcn_varpulse.mmodels a variable width pulse generator. The S-function uses two DWork vectors. The first DWork vector stores the pulse width value, which is modified at every major time step in theUpdatemethod. The second DWork vector stores the handle of the pulse generator block in the Simulink model. The value of this DWork vector does not change over the course of the simulation.

ThePostPropagationSetupmethod, calledDoPostPropSetupin this S-function, sets up the two DWork vectors.

function DoPostPropSetup(block) % Initialize the Dwork vector block.NumDworks = 2; % Dwork(1) stores the value of the next pulse width block.Dwork(1).Name = 'x1'; block.Dwork(1).Dimensions = 1; block.Dwork(1).DatatypeID = 0; % double block.Dwork(1).Complexity = 'Real'; % real block.Dwork(1).UsedAsDiscState = true; % Dwork(2) stores the handle of the Pulse Geneator block block.Dwork(2).Name = 'BlockHandle'; block.Dwork(2).Dimensions = 1; block.Dwork(2).DatatypeID = 0; % double block.Dwork(2).Complexity = 'Real'; % real block.Dwork(2).UsedAsDiscState = false;

TheStartmethod initializes the DWork vector values.

function Start(block) % Populate the Dwork vector block.Dwork(1).Data = 0; % Obtain the Pulse Generator block handle pulseGen = find_system(gcs,'BlockType','DiscretePulseGenerator'); blockH = get_param(pulseGen{1},'Handle'); block.Dwork(2).Data = blockH;

TheOutputsmethod uses the handle stored in the second DWork vector to update the pulse width of the Pulse Generator block.

function Outputs(block) % Update the pulse width value set_param(block.Dwork(2).Data, 'PulseWidth', num2str(block.InputPort(1).data));

TheUpdatemethod then modifies the first DWork vector with the next value for the pulse width, specified by the input signal to the S-Function block.

function Update(block) % Store the input value in the Dwork(1) block.Dwork(1).Data = block.InputPort(1).Data; %endfunction

See Also

|||

Related Topics