从Matlab-Simulink生成易读可重用代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
从Matlab-Simulink生成易读可重用代码
从Matlab Simulink生成易读可重用代码
by: 吴少风
MATLAB提供从MATLAB代码或simulink模型生成C/C++代码的功能。
从MATLAB 2011b版开始,MATLAB将代码生成Coder作为单独模块发布。
MATLAB每年更新两次,经过不断完善,新版本的Coder功能更强大。
用MATLAB生成C/C++代码具有MATLAB Coder、Simulink Coder、Embedded Coder三个功能模块,MATLAB Coder从MATLAB 代码生成代码,Simulink Coder从Simulink模型生成代码,Embedded Coder结合MATLAB Coder和Simulink Coder,生成嵌入式代码。
利用代码生成功能,可以快速从模型生成可靠的代码,应用越来越广泛。
要生成易于阅读、重用性好的代码,必须进行详细设置。
文中内容以易读、可重用为目标,建立嵌入式代码生成的演示模型,了解Simulink 代码生成相关工具,介绍详细设置步骤,最终生成容易阅读、可重用代码,供单处理器单任务实时嵌入式系统应用。
文中的方法为严格控制生成
代码的个人总结。
以文档呈现,方便自己今后查看,也希望能为其他人提供一些方便。
1.简单示例
本部分搭建一个简单的PI控制器模型,示范模型建立、设置、生成代码的详细步骤。
1)新建嵌入式代码生成模型,
MATLAB->simulink,New / Embedded Coder / Code Generation System。
不选择一
般simulink模板,可减少模型配置参数的
设置。
2)搭建如错误!未找到引用源。
所示简
易模型,保存文档,设置文件名。
图 1. 一个简单示例模型
3)点击工具栏图标,设置模型配置
参数,应用并保存。
对嵌入式应用,固定步
4)
5)interface: 设置整个模型生成代码的接口。
✧code interface package,可选择可重
用,Pass root level I/O as,模型输入输出参数一般较多,一般选择结构体,structure reference,模型数据、输入、输出通过各自独立结构体传入参数;
part of model data structure,一个结构体传入参数。
也可选择不可重用。
✧configure model functions,点击进
入,设置模型具体的C原型。
get default configuration,可修改模型默认initialize/step函数名,及参数,各输入输出单独作为函数参数,这与结构体传参是矛盾的,不能同时设置。
➢code style: 设置代码风格。
✧Parentheses括号,--
Nominal(readability),按可读性优化。
✧Casting mode 强制转换方式,
Nominal.
✧Code indentation 代码缩进,size --
4.
➢Code placement: 代码放置,可设置变
量定义或声明在单独文件还是和源代码放
一起,头文件包含是< head.h >还是"
head.h "。
➢Data type replacement: 数据类型替
换。
6)设置模型中每一个基本模块的属
性。
包括名称、值、数据类型、采样时间等。
子模块或者引用模型等这类自定义模块,除了内部基本模块的属性外,还要设置各自的模块属性。
模块中参数等值,必须按照设计配置;如果想使用可调参数,则将参数设置为变量,再设置变量值。
生成代码模型中的模块名设置,最好遵循目标语言的命名规则,因为生成代码中的一些名称可以从模块名继承。
嵌入式应用大多无浮点单元,定点数据的设置在模块属性的代码生成栏。
将图1中各模块可按如下方式设置:
●inport,点击模块下方名称,设置模块名,将其设置为In;双击模块进入模块属性设置,main栏设置编号,编号会体现在子系统或引用模型上;signal attributes设置数据类型为定点数,16b字长10b小数部分fixdt(1,16,10)。
其它模块设置方法类似。
●view->model data,弹出model data窗口。
simulink提供的model data窗口,用于显示当前层级下的所有输入输出、信号、状态、参数,并将对应属性罗列成表格,而且表格可编辑部分属性。
●Kp增益模块,双击模块,输出数据类型设置为同输入,参数数据类型设置为从Gain继承,Gain设置为Kp。
●在model data窗口,参数栏,Kp模块,值变为Kp,其后出现create...链接字样。
点击弹出create new data窗口,值选择Simulink.Parameter,位置选择Base Workspace,创建,弹出Simulink.Parameter: Kp属性窗口,设置值为10,数据类型为定点数fixdt(1,16,10),存储类型选择
ExportedGlobal,确定。
●Ki增益模块,使用设置Kp的方法将
simulink参数属性值设为1。
●File->Model properties,弹出模型属性
窗口,选择数据栏,将数据定义到数据字典,选择或新建一个数据字典文件,应用。
建立
在基本工作区的数据迁移到数据字典保存。
后面该模型新建参数等数据,基本工作区的
位置将被数据字典代替。
保存在基本工作区
的数据,关闭MATLAB不会自动保存,因
此一些模型也采用脚本配置。
位置也可选择
模型工作区,但保存到模型工作区的参数,
有效的存储类型会受到限制。
●unit delay单位延时,初始条件设为0,
状态名称按实际意义设置。
●Outport,数据类型可选自动。
信号名称,可到model data窗口统一设置,该窗口中选中信号,模型区会用颜色标记对应标记。
没有设置名称的信号,按照内部规则生成代
码。
模型相关设置,simulink还提供model explorer图形界面统一管理。
点击图标可打开。
7)设置完成后,启用Advisor检查模型
设置。
选择检查项目,运行检查,修改不符
合的项目。
analysis -> model advisor,针对模型,可选项目包括MISRA、ISO26262等。
选中by task,右侧点击run selected checks。
analysis -> data type design -> fixed point tool,进入设置后,左侧选择项目,右侧运行检查。
code -> C/C++ code -> code generation advisor,针对生成代码,可选项目有空间效率、执行效率、可追踪性、安全预警、MISRA C: 2012 guidelines等。
检查项目可能会弹出一些警告,是之前手动设置的,这时选择忽略。
比如内联参数有效率,但想要用可调参数,就只能忽略检查时的警告。
8)点击图标,编译模型生成代码。
完成后可查看报告。
算法代码如下:
数据定义如下:
2.Simulink生成代码相关工具
在“1简单示例”一节,介绍了代码生成的详细过程。
其中一些常用的工具及菜单,现罗列于表1中。
表 1. 常用工具及菜单
图
标
名称
最方便的
位置
功能
Library Browser 工具栏图
标
基本模块库,搭
建模型的基本元
素所在库。
Model Configuration 工具栏图
标
模型配置参数,
模型仿真、生成
Parameters
代码所依赖的全局规则。
Mode Data
菜单
View----
-Mode
Data
列表显示当前层
级模型的信号、
参数、状态等,
可以在此处集中
编辑。
Model
Explorer
工具栏图
标
树状结构的模型
管理器,包括数
据、配置、子模
块等。
从树状结
构可以看出,每
一个模型都单独
包含数据数据、
配置等元素。
Model
Advisor
工具栏图
标
根据选定项,针
对模型设计,进
行检查,提供建
议。
用户根据建
议修改自己的模
型。
Code Model 根据选定项,针
Generation
Advisor
Advisor----
图标下拉
对代码生成设
置,进行检查,
提供建议。
用户
根据建议修改自
己的模型。
Fixed-Point
Tool
菜单
Analysis
---- - data
Type
Design -
Fixed-Point
Tool
针对定点数设
计,进行检验,
提供建议。
用户
可以根据建议修
改自己的模型。
Build Model
工具栏图
标
根据配置,编译
模型生成代码。
图标下拉栏还
有:编译备选子
系统,嵌入式代
码快速向导。
快
速向导按步骤生
成新配置,并依
次生成代码。
Run 工具栏图模型仿真运行。
标一般首先会用仿
真验证模型。
3.Coder保留的默认名称
在“1简单示例”一节,生成的代码中出现了一些固定的名称,这些是代码生成器保留的默认名称,用户不能改变。
为方便理解生成的代码,将这些默认名称及含义列于表1中。
表 2. 生成代码中的默认名称
默认名称含义
默认名
称
含义
U 整个模型
的输入模
块
local 局部变量加的
前缀
Y 整个模型rt 全局变量的前
的输出模
块
缀,可设置
B 模块输出
信号
rtb 局部模块输出
的前缀,可设置
P 模块参数_T 默认类型后缀,
可替换
DW 离散模块
状态
step 模型入口,可设
置
DefaultP 默认参数initialize 模型初始化,可
设置
Ext 全局类型
加的前缀
4.代码重用
该部分将搭建一个稍微复杂模型,封装参数,生成可重用代码。
1)建立如错误!未找到引用源。
模型。
图 2. PID模型
2)选中上面模型,右键,create subsystem from selection.进入子系统,按上面介绍的方法编辑各基本模块。
为信号和状态起名,设置输入数据类型,输出数据类型和输入保持一致。
参数设置为结构体,比如KpGain的值设置为pid.Kp,数据类型继承。
3)返回模型上一级,修改子系统名称为Dpid,选中子系统右键-> mask -> edit mask,在parameter选项卡,编辑参数,将名称设为pid。
4)右键->subsystem parameters,勾选treat as atomic unit,function packing设为reusable,函数名设为UnSatIntPid。
5)打开model explorer,在数据字典中
添加simulink bus类,选中该类,右下角launch bus editor进入编辑,设置类名称为PidParaStrc,将参数按名称依次添加到类,并设置基本数据类型。
6)在数据字典中添加simulink parameter对象,将对象数据名称设为DpidPar,类型设为PidParaStrc,值设为struct,存储类型设为ExportedGlobal。
在DpidPar值属性列,编辑与PidParaStrc类成员对应的参数名称,并赋值。
将simulink 参数DpidPar复制一份,编辑其参数值。
7)将子系统Dpid复制一份,名称改为Qpid,设置mask参数为QpidPar,连上输入输出,最终模型如图所示。
图 3. 代码重用演示模型
8)设置好模型配置参数,编译生成代
码,查看生成的报告。
整个模型的代码如下,调用两次UnSatIntPid函数,分别传入不同的参数。
生成可重用的算法如下所示,函数名为设置的UnSatIntPid,函数参数有四个,依次是给定,反馈,子系统状态,PidParaStrc参数。
5.数据重用
嵌入式应用多用查表的方式实现较复杂的数学函数,比如三角函数。
而且为了保证精度,表格的数据一般较多。
通常,如正弦函数,会充分利用周期性对称性,查找(0, pi/2)的sin表格。
本部分将演示,将(0, pi/2)的sin表格定义为全局const变量,单独放在一个文件,实现sin/cos函数。
1)建立如图4模型实现sin查表。
图 4. sin查表模型
模型输入为无符号短整型,执行环境下输入角度信号,ufix(16, 15)类型,1代表360度。
输出为sfix(16, 15),为sin查表值。
模型使用同一个[0,pi/2)的sin表,表长256,表数据类型同输出。
2)设置查表模块名称为SinTab90d,右
击设置属性,表格数据设置为SinTab90d,
数据类型继承。
对SinTab90d建立
Simulink.Patameter对象,保存到数据字
典。
参数值设置为sin( [ 0 : pi/2/255 : pi/2 ] ),数据类型设置为fixdt(1,16,15),存
储类型设置为ConstVariable(Custom),定
义文件、头文件设置为LkupTab。
然后复
制出其余四个查表模块。
3)将模型封装为可重用子模块。
4)按同样的方法,可利用[0,pi/2)的sin
表格实现cos查表。
5)最后建立如图5模型,对算法进行
仿真,验证算法输出是否没有错误。
图 5. 正弦查表算法仿真验证
仿真结果如图6,从图中可看出,一个周期内计算结果均正确,算法得以验证。
图 6. 正弦查表模型仿真波形
6)剔除仿真用的信号发生和示波器,接输入输出端口,设置,然后生成代码。
整个模型的入口函数为:
按配置,模型为表格生成单独的文件:
生成可重用的LkupSin函数如下,函数第一个参数为输入,第二个参数为输出。
更多使用方法,请参见MATLAB软件help。