S-Function小结

模板函数相关概念

Matlab提供了一个S-Function函数模板,一般直接在模板上稍加修改加以利用,模板函数可通过一下路径进行查找:
1、Polyspace\R2020a\toolbox\simulink\blocks\sfuntmpl.m
2、在matlab的命令行窗口输入edit sfuntmpl
可直接另存为到相关文件夹,并修改相关函数名

在这里插入图片描述
S-function name:填入S-function的函数名称;
S-function parameters:填入S-function需要输入的外部参数的名称,如果有多个变量的话,中间用逗号隔开,如a,b,c。
使用edit关联到编辑好的S-Function函数,并将函数名称修改为函数名。

S函数控制流

在这里插入图片描述

在这里插入图片描述
模板函数的定义形式为function[sys,x0,str,ts]=sfuntmpl(t,x,u,flag),一般来说,S函数的定义形式为[sys,x0,str,ts]=sfunc(t,x,u,flag,p1,…Pn),其中的sfunc为自己定义的函数名称,以上参数中,t、x、u分别对应时间、状态、输入信号,flag为标志位,其取值不同,S函数执行的任务和返回的数据也是不同的,pn为额外的参数,sys为一个通用的返回参数值,其数值根据flag的不同而不同,x0为状态初始数值,str在目前为止的matlab版本中并没有什么作用,一般str=[]即可。
一般只需在模板函数上修改一下几处即可:
【1】[sys,x0,str,ts]=sfunc(t,x,u,flag,p1,…Pn),函数名根据喜好进行修改,u为模块输入,其次可增加p1,…Pn参数,对应于S-function模块界面的S-function parameters,可在模块界面进行外部参数设置;
【2】在function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes初始化函数里进行参数设置,状态变量个数、输入、输出及初始值设置;
【3】在相应的功能函数下进行功能函数编写,注意将相关函数名字修改与第一行一致。

例:state-space equation函数实现

state-space equation
输入信号u=cos(t),输出x1,x2

方法一:Simulink模块实现

结构图
使用Continuous>State-Space模块,设置参数如下:
State-Space参数设置

方法二:S-Function函数实现

结构图
无S-function parameters:
在这里插入图片描述
初始值:在这里插入图片描述

在这里插入图片描述
注意x1和x2的导数书写方式如下:
在这里插入图片描述
当输出为1个以上时,可使用一下两种方式进行书写:
在这里插入图片描述

方法三:Matlab代码实现

// A code block
A=[0 1;-0.8 -0.5];B=[0 ;0.9];C=[1 0;0 1];D=[0;0];
sys=ss(A,B,C,D);
x0=[1 ;3] ;t=[0:0.01:10];u=cos(t);[y T x]=lsim(sys,u,t,x0);
plot(T,x(:,1));plot(T,x(:,2));

例:y=kx函数

在这里插入图片描述
将使用3个S-function parameters并进行封装,代码如下:

// An highlighted block
function [sys,x0,str,ts,simStateCompliance] = kx(t,x,u,flag,k1,k2,k3)
switch flag,
  case 0,
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
  case 1,
    sys=mdlDerivatives(t,x,u);
  case 2,
    sys=mdlUpdate(t,x,u);
  case 3,
    sys=mdlOutputs(t,x,u,k1,k2,k3);   %增加k1,k2,k3
  case 4,
    sys=mdlGetTimeOfNextVarHit(t,x,u);
  case 9,
    sys=mdlTerminate(t,x,u
  otherwise
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
end

function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates  = 0;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;   % at least one sample time is needed
sys = simsizes(sizes);
x0  = [];
str = [];
ts  = [0 0];
simStateCompliance = 'UnknownSimState';


function sys=mdlDerivatives(t,x,u)
sys = [];

function sys=mdlUpdate(t,x,u)
sys = [];

function sys=mdlOutputs(t,x,u,k1,k2,k3) %增加k1,k2,k3
  if (u<-3)
      sys=k1*u;
  elseif (u>-3&&u<3)
      sys=k2*u;
  else 
      sys=k3*u;
  end

function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;    %  Example, set the next hit to be one second later.
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];

可在S-function parameters进行参数设置,k1,k2,k3之间用逗号隔开:
在这里插入图片描述
封装完将k1,k2,k3设置为模块参数:
在这里插入图片描述
在这里插入图片描述

S-Function 可以使用MATLAB®,C,C ,Ada,或Fortran 语言来编写。使用MEX 实用工具,将C,C ,Ada,和Fortran 语言的S-Function 编译成MEX-文件,在需要的时候,它们可与其它的MEX-文件一起动态地连接到MATLAB 中。 S-Function 使用一种特殊的调用格式让你可以与Simulink 方程求解器相互作用,这与发生在求解器和内置Simulink 块之间的相互作用非常相似。S-Function 的形式是非常通用的,且适用于连续、离散和混合系统。 S-function 为你提供了一种在Simulink 模型中增加自制块的手段,你可以使用MATLAB,C,C ,Ada,或Fortran 语言来创建自己的块。按照下面一套简单的规则,你可以在S-function 中实现自己的算法。在你编写一个S-Functin 函数,并将函数名放置在一个S-Functin 块中(在用户定义的函数块库中有效)之后,通过使用masking 定制用户界面。 目录 S-FUNCTION 概述.......... 1 什么是 S-FUNCTION...... 2 在模型中使用S-FUNCTION...... 3 向 S-Function 传递参数....... 3 何时使用 S-Function 4 S-FUNCTION 的工作原理.......... 5 Simulink 块的数学关系........ 5 仿真过程......... 5 S-Function 回调程序. 6 S-FUNCTION 的实现...... 8 M-文件的S-Function.......... 8 MEX 文件的S-function ....... 8 MEX 文件与M-文件的S-function 比较... 9 S-FUNCTION 的概念..... 10 直接馈通....... 10 动态维矩阵... 10 设置采样时间和偏移量.......11 S-FUNCTION 范例........ 14 M 文件S-function 范例...... 15 C S-Function 范例... 16 Fortran S-Function 范例.... 18 C S-Function 范例......... 18 Ada S-Function 范例......... 18 编写 M S-FUNCTION.... 19 概述........ 20 S-Function 参数...... 20 S-Function 的输出... 20 定义 S-FUNCTION 块特性....... 22 处理 S-FUNCTION 参数 22 M 文件的S-FUNCTION 范例... 23 范例 1——简单的M 文件S-Function ... 23 范例 2——连续状态S-Function . 25 范例 3——离散状态S-Function . 27 范例 4——混合系统S-Function . 28 范例 5——变步长S-Function ..... 31 ii 使用C 语言编写S-FUNCTION .......... 33 概述........ 34 创建 C MEX S-Function.... 35 自动生成 S-FUNCTION 36 配置生成的 S-Function...... 37 S-Function Builder 如何生成S-Function......... 37 设置 include 路径.... 37 S-FUNCTION BUILDER 的对话窗........ 39 Initialization 选卡..... 39 Data Properties 选卡......... 40 Libraries 选卡.......... 42 Outputs 选卡 43 Continuous Derivatives 选卡....... 45 Discrete Update 选卡........ 46 Build Info 选卡........ 47 一个基本的 C MEX S-FUNCTION 范例....... 48 定义与包含... 49 回调函数的实现...... 50 Simulink/Real-Time Workshop 接口..... 51 Building Timestwo 范例..... 51 C S-FUNCTION 模板..... 52 S-Function 源文件必需的内容..... 52 SimStruct...... 53 编译 C S-Function.. 53 SIMULINK 如何与C S-FUNCTION 相互作用 54 进程层面....... 54 数据层面....... 56 编写回调函数... 59 将 LEVEL 1 C MEX S-FUNCTION 转换到LEVEL 2 . 60 创建 C S-FUNCTION 63 创建 ADA S-FUNCTION.......... 64 创建 FORTRAN S-FUNCTION 65 实现块特性 67 对话框参数....... 68 iii 可调参数....... 68 运行参数 70 创建运行参数.......... 70 更新运行参数.......... 71 创建输入和输出端口... 72 创建输入端口.......... 72 创建输出端口.......... 73 输入的标量扩展...... 74 掩码多端口 S-Function...... 75 自定义数据类型.......... 76 采样时间 77 基于块的采样时间... 77 指定基于端口的采样时间.. 79 基于块与基于端口的混合采样时间 ........ 81 多速率 S-Function 块......... 82 多速率 S-Function 块的同步........ 83 工作向量 84 工作向量与过零检测.......... 85 包括指针工作向量的范例.. 85 内存分配....... 86 FUNCTION-CALL 子系统.......... 87 错误处理 89 防超程代码... 89 SsSetErrorStatus 的终止条件..... 90 数组边界检查.......... 90 S-FUNCTION 范例........ 91 连续状态的 S-Function 范例........ 92 离散状态的 S-Function 范例........ 93 混合系统的S-Function 范例........ 93 变步长的 S-Function 范例. 94 过零检测的 S-Function 范例........ 94 时变连续传递函数的 S-Function 范例... 94
在FreeSWITCH中,export是一个非常重要的概念。它可以将一个模块的函数或变量暴露给其他模块使用。本文将介绍export的原理及应用。 首先,我们需要了解FreeSWITCH的模块系统。FreeSWITCH采用动态加载模块的方式来扩展功能。每个模块都是一个动态库,可以通过mod_开头的模块名进行加载。模块可以定义自己的函数和变量,并且可以使用其他模块的函数和变量。 然而,有些函数和变量是不想被其他模块使用的。为了避免名称冲突和保护模块的内部实现,FreeSWITCH采用了一种叫做“隐藏”的机制。也就是说,模块定义的函数和变量默认情况下是无法被其他模块访问的。 这时,export就派上用场了。通过在模块中定义export表,可以将指定的函数和变量暴露给其他模块使用。export表是一个静态的数组,其中每个元素包含了要export的函数或变量的名字和地址。当模块被加载时,系统会扫描所有模块的export表,并将需要的函数和变量地址保存起来,以便其他模块调用。 下面是一个简单的例子,演示了如何在模块中使用export: ```c #include <switch.h> SW_EXPORT(void) say_hello(const char *name) { printf("Hello, %s!\n", name); } static switch_status_t my_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) { static switch_api_interface_t api = { 0 }; *module_interface = switch_loadable_module_create_module_interface(pool, MOD_MY_MODULE); api.say_hello = say_hello; switch_api_interface_t *api_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_API_INTERFACE); *api_interface = api; return SWITCH_STATUS_SUCCESS; } SW_MODULE_ENTRY(my_module) { switch_api_interface_t *api_interface; *module_interface = switch_loadable_module_create_module_interface(pool, MOD_MY_MODULE); SWITCH_ADD_API(api_interface, "my_module", "Say hello", say_hello, "Say hello to someone"); return SWITCH_STATUS_SUCCESS; } ``` 在这个例子中,我们定义了一个名为say_hello的函数,然后将它添加到了export表中。在模块加载时,系统会自动将say_hello的地址保存到export表中。其他模块可以通过switch_loadable_module_get_exported_function()函数来获取say_hello函数的地址,从而调用它。 export在FreeSWITCH中有广泛的应用。例如,mod_dptools模块就定义了大量的export函数,供其他模块使用。除此之外,许多第三方模块也使用了export机制,以提供更加灵活的扩展性。 总之,export是FreeSWITCH模块系统中非常重要的一个概念,它可以帮助我们编写更加灵活和高效的模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值