Level2-S-function
level2的S函数可以允许多个输入和输出,且其可以包含任何的数据类型。
1、首先要更改msfuntmpl为自己需要的函数名
2、修改初始化函数setup,该函数传入了一个block对象作为参数
- 修改输入输出的端口数目 block.NumInputPorts、block.NumOutputPorts
- 确定输入输出端口的数据类型block.InputPort(1).DatatypeID、block.InputPort(1).Complexity 、 block.OutputPort(1).DatatypeID、block.OutputPort(1).Complexity
- 确定参数个数及block.NumDialogPrms(模块GUI参数个数) 、block.DialogPrmsTunable(指定哪些 S-Function 的对话框参数是可调的)
- 确定连续状态变量数目NumContStates
- 确定采样时间block.SampleTimes
- block.SetAccelRunOnTLC(指定是否使用此模块的 TLC 文件为使用它的模型生成仿真目标)
- 后面就是注册一系列需要调用的函数了。
3、CheckPrms用于检查输入的参数是否正确
4、DoPostPropSetup用于初始化Dwork工作向量,规定其个数及每个向量的维数,数据类型、离散状态变量名称和虚实性(当不同的S函数模块之间需要通过全局变量或静态变量进行数据交互时,必须使用Dwork向量来进行存储)
5、InitializeConditions用于初始化状态变量的值或者Dwork的值
6、start函数与InitializeConditions功能一致,但是其仅在仿真开始的时候初始化一次,InitializeConditions是在每次子系统使能时都能被调用。
7、output函数用于计算S函数的输出
8、update用于计算离散状态变量的值
9、Derivatives方法用于计算连续状态的值
10、Terminate用于终止
function msfuntmpl(block) %MSFUNTMPL A Template for a MATLAB S-Function % The MATLAB S-function is written as a MATLAB function with the % same name as the S-function. Replace 'msfuntmpl' with the name % of your S-function. % Copyright 2003-2018 The MathWorks, Inc. % % The setup method is used to setup the basic attributes of the % S-function such as ports, parameters, etc. Do not add any other % calls to the main body of the function. % setup(block); %endfunction % Function: setup =================================================== % Abstract: % Set up the S-function block's basic characteristics such as: % - Input ports % - Output ports % - Dialog parameters % - Options % % Required : Yes % C MEX counterpart: mdlInitializeSizes % function setup(block) % Register the number of ports. block.NumInputPorts = 1; block.NumOutputPorts = 1; % Set up the port properties to be inherited or dynamic. block.SetPreCompInpPortInfoToDynamic; block.SetPreCompOutPortInfoToDynamic; % Override the input port properties. block.InputPort(1).DatatypeID = 0; % double block.InputPort(1).Complexity = 'Real'; % Override the output port properties. block.OutputPort(1).DatatypeID = 0; % double block.OutputPort(1).Complexity = 'Real'; % Register the parameters. block.NumDialogPrms = 3; block.DialogPrmsTunable = {'Tunable','Nontunable','SimOnlyTunable'}; % Set up the continuous states. block.NumContStates = 1; % Register the sample times. % [0 offset] : Continuous sample time % [positive_num offset] : Discrete sample time % % [-1, 0] : Inherited sample time % [-2, 0] : Variable sample time block.SampleTimes = [0 0]; % ----------------------------------------------------------------- % Options % ----------------------------------------------------------------- % Specify if Accelerator should use TLC or call back to the % MATLAB file block.SetAccelRunOnTLC(false); % Specify the block's operating point compliance. The block operating % point is used during the containing model's operating point save/restore) % The allowed values are: % 'Default' : Same the block's operating point as of a built-in block % 'UseEmpty': No data to save/restore in the block operating point % 'Custom' : Has custom methods for operating point save/restore % (see GetOperatingPoint/SetOperatingPoint below) % 'Disallow': Error out when saving or restoring the block operating point. block.OperatingPointCompliance = 'Default'; % ----------------------------------------------------------------- % The MATLAB S-function uses an internal registry for all % block methods. You should register all relevant methods % (optional and required) as illustrated below. You may choose % any suitable name for the methods and implement these methods % as local functions within the same file. % ----------------------------------------------------------------- % ----------------------------------------------------------------- % Register the methods called during update diagram/compilation. % ----------------------------------------------------------------- % % CheckParameters: % Functionality : Called in order to allow validation of the % block dialog parameters. You are % responsible for calling this method % explicitly at the start of the setup method. % C MEX counterpart: mdlCheckParameters % block.RegBlockMethod('CheckParameters', @CheckPrms); % % SetInputPortSamplingMode: % Functionality : Check and set input and output port % attributes and specify whether the port is operating % in sample-based or frame-based mode % C MEX counterpart: mdlSetInputPortFrameData. % (The DSP System Toolbox is required to set a port as frame-based) % block.RegBlockMethod('SetInputPortSamplingMode', @SetInpPortFrameData); % % SetInputPortDimensions: % Functionality : Check and set the input and optionally the output % port dimensions. % C MEX counterpart: mdlSetInputPortDimensionInfo % block.RegBlockMethod('SetInputPortDimensions', @SetInpPortDims); % % SetOutputPortDimensions: % Functionality : Check and set the output and optionally the input % port dimensions. % C MEX counterpart: mdlSetOutputPortDimensionInfo % block.RegBlockMethod('SetOutputPortDimensions', @SetOutPortDims); % % SetInputPortDatatype: % Functionality : Check and set the input and optionally the output % port datatypes. % C MEX counterpart: mdlSetInputPortDataType % block.RegBlockMethod('SetInputPortDataType', @SetInpPortDataType); % % SetOutputPortDatatype: % Functionality : Check and set the output and optionally the input % port datatypes. % C MEX counterpart: mdlSetOutputPortDataType % block.RegBlockMethod('SetOutputPortDataType', @SetOutPortDataType); % % SetInputPortComplexSignal: % Functionality : Check and set the input and optionally the output % port complexity attributes. % C MEX counterpart: mdlSetInputPortComplexSignal % block.RegBlockMethod('SetInputPortComplexSignal', @SetInpPortComplexSig); % % SetOutputPortComplexSignal: % Functionality : Check and set the output and optionally the input % port complexity attributes. % C MEX counterpart: mdlSetOutputPortComplexSignal % block.RegBlockMethod('SetOutputPortComplexSignal', @SetOutPortComplexSig); % % PostPropagationSetup: % Functionality : Set up the work areas and the state variables. You can % also register run-time methods here. % C MEX counterpart: mdlSetWorkWidths % block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup); % ----------------------------------------------------------------- % Register methods called at run-time % ----------------------------------------------------------------- % % ProcessParameters: % Functionality : Call to allow an update of run-time parameters. % C MEX counterpart: mdlProcessParameters % block.RegBlockMethod('ProcessParameters', @ProcessPrms); % % InitializeConditions: % Functionality : Call to initialize the state and the work % area values. % C MEX counterpart: mdlInitializeConditions % block.RegBlockMethod('InitializeConditions', @InitializeConditions); % % Start: % Functionality : Call to initialize the state and the work % area values. % C MEX counterpart: mdlStart % block.RegBlockMethod('Start', @Start); % % Outputs: % Functionality : Call to generate the block outputs during a % simulation step. % C MEX counterpart: mdlOutputs % block.RegBlockMethod('Outputs', @Outputs); % % Update: % Functionality : Call to update the discrete states % during a simulation step. % C MEX counterpart: mdlUpdate % block.RegBlockMethod('Update', @Update); % % Derivatives: % Functionality : Call to update the derivatives of the % continuous states during a simulation step. % C MEX counterpart: mdlDerivatives % block.RegBlockMethod('Derivatives', @Derivatives); % % Projection: % Functionality : Call to update the projections during a % simulation step. % C MEX counterpart: mdlProjections % block.RegBlockMethod('Projection', @Projection); % % SimStatusChange: % Functionality : Call when simulation enters pause mode % or leaves pause mode. % C MEX counterpart: mdlSimStatusChange % block.RegBlockMethod('SimStatusChange', @SimStatusChange); % % Terminate: % Functionality : Call at the end of a simulation for cleanup. % C MEX counterpart: mdlTerminate % block.RegBlockMethod('Terminate', @Terminate); % % GetOperatingPoint: % Functionality : Return the operating point of the block. % C MEX counterpart: mdlGetOperatingPoint % block.RegBlockMethod('GetOperatingPoint', @GetOperatingPoint); % % SetOperatingPoint: % Functionality : Set the operating point data of the block using % from the given value. % C MEX counterpart: mdlSetOperatingPoint % block.RegBlockMethod('SetOperatingPoint', @SetOperatingPoint); % ----------------------------------------------------------------- % Register the methods called during code generation. % ----------------------------------------------------------------- % % WriteRTW: % Functionality : Write specific information to model.rtw file. % C MEX counterpart: mdlRTW % block.RegBlockMethod('WriteRTW', @WriteRTW); %endfunction % ------------------------------------------------------------------- % The local functions below are provided to illustrate how you may implement % the various block methods listed above. % ------------------------------------------------------------------- function CheckPrms(block) a = block.DialogPrm(1).Data; if ~isa(a, 'double') me = MSLException(block.BlockHandle, message('Simulink:blocks:invalidParameter')); throw(me); end %endfunction function ProcessPrms(block) block.AutoUpdateRuntimePrms; %endfunction function SetInpPortFrameData(block, idx, fd) block.InputPort(idx).SamplingMode = fd; block.OutputPort(1).SamplingMode = fd; %endfunction function SetInpPortDims(block, idx, di) block.InputPort(idx).Dimensions = di; block.OutputPort(1).Dimensions = di; %endfunction function SetOutPortDims(block, idx, di) block.OutputPort(idx).Dimensions = di; block.InputPort(1).Dimensions = di; %endfunction function SetInpPortDataType(block, idx, dt) block.InputPort(idx).DataTypeID = dt; block.OutputPort(1).DataTypeID = dt; %endfunction function SetOutPortDataType(block, idx, dt) block.OutputPort(idx).DataTypeID = dt; block.InputPort(1).DataTypeID = dt; %endfunction function SetInpPortComplexSig(block, idx, c) block.InputPort(idx).Complexity = c; block.OutputPort(1).Complexity = c; %endfunction function SetOutPortComplexSig(block, idx, c) block.OutputPort(idx).Complexity = c; block.InputPort(1).Complexity = c; %endfunction function DoPostPropSetup(block) block.NumDworks = 2; 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; block.Dwork(2).Name = 'numPause'; block.Dwork(2).Dimensions = 1; block.Dwork(2).DatatypeID = 7; % uint32 block.Dwork(2).Complexity = 'Real'; % real block.Dwork(2).UsedAsDiscState = true; % Register all tunable parameters as runtime parameters. block.AutoRegRuntimePrms; %endfunction function InitializeConditions(block) block.ContStates.Data = 1; %endfunction function Start(block) block.Dwork(1).Data = 0; block.Dwork(2).Data = uint32(1); %endfunction function WriteRTW(block) block.WriteRTWParam('matrix', 'M', [1 2; 3 4]); block.WriteRTWParam('string', 'Mode', 'Auto'); %endfunction function Outputs(block) block.OutputPort(1).Data = block.Dwork(1).Data + block.InputPort(1).Data; %endfunction function Update(block) block.Dwork(1).Data = block.InputPort(1).Data; %endfunction function Derivatives(block) block.Derivatives.Data = 2*block.ContStates.Data; %endfunction function Projection(block) states = block.ContStates.Data; block.ContStates.Data = states+eps; %endfunction function SimStatusChange(block, s) block.Dwork(2).Data = block.Dwork(2).Data+1; if s == 0 disp('Pause in simulation.'); elseif s == 1 disp('Resume simulation.'); end %endfunction function Terminate(block) disp(['Terminating the block with handle ' num2str(block.BlockHandle) '.']); %endfunction function operPointData = GetOperatingPoint(block) % package the Dwork data as the entire operating point of this block operPointData = block.Dwork(1).Data; %endfunction function SetOperatingPoint(block, operPointData) % the operating point of this block is the Dwork data (this method % typically performs the inverse actions of the method GetOperatingPoint) block.Dwork(1).Data = operPointData; %endfunction