楼主
工作并不用Simulink做功能开发,但在MBD流行的今天,Simulink已成为汽车电子领域开发的主流工具,楼主在学校时经常用Matlab/Simulink做嵌入式开发,到了工作在空闲时间也会不间断学习一波,很大一部分原因在于楼主个人对该工具的喜爱,但Simulink生成的代码真的不想说太多,即使用一些配置手段去优化生成的代码,代码依然存在可读性差和执行顺序乱的特点。
这里插一段:Simulink与楼主工作所用的工具相比,在仿真验证方面,Simulink无疑优势很大,而在代码质量和可读性方面则差很多,但工具只是一种手段,每个人用着习惯就行,对于功能开发者来说最重要的还是功能逻辑的实现
条件编译
使用条件编译,可以限定程序中某些内容只有在满足一定条件下才能参与编译。因此,利用条件编译可使同一源程序在不同编译条件下产生不同的目标代码。例如在汽车电子功能开发过程中,同一车型可能会有不同配置,但各个配置的功能我们可能都已开发完成,此时只需要在同一源代码中,根据具体项目的配置去生成不同的软件,常用的条件编译语句主要有下面五种形式:
1
形式一
#if 常量表达式
程序段 //当“常量表达式”非零时编译该程序段
#endif
2
形式二
#if 常量表达式
程序段1 //当“常量表达式”非零时编译该程序段
#else
程序段2 //当“常量表达式”为零时编译该程序段
#endif
3
形式三
#if 常量表达式1
程序段1 //当“常量表达式1”非零时编译该程序段
#elif 常量表达式2
程序段2 //当“常量表达式1”为零,“常量表达式2”非零时时编译该程序段
.
.
#elif 常量表达式n
程序段n //当“常量表达式1”为零,...“常量表达式n”非零时时编译该程序段
#else
程序段n+1 //其余情况下编译该程序段
#endif
4
形式四
#ifdef 标识符
程序段1
#else
程序段2
#endif
如果“标识符”经#define 定义过且未经undef删除,则编译程序段1,否则编译程序段2。
5
形式五
#ifndef 标识符
程序段1
#else
程序段2
#endif
如果“标识符”未被定义,则编译程序段1,否则编译程序段2。
Simulink实现条件编译
如何用Simulink生成如下代码?
#if K==1
z = (x + y) * K1;
#elif K == 2
z = x / y * K2;
#endif
一、使用可变子系统模块Variant Subsystem
根据如上需实现的代码,建立如下Simulink模型:
当创建如上模型后,需对Block Parameters属性进行配置。
然后在数据字典中设置三个信号变量x、y、z和三个参数变量K、K1及K2,信号变量x、y、z可理解为标定工具中可调的测量变量;参数变量K1和K2可理解为可标定变量;而参数变量K的取值则决定哪支分支参与编译。
当模型和数据设置完成,需要将Simulink模型中设置的信号和参数与数据字典相对应的变量进行关联,如何将信号与数据字典变量进行关联,这里介绍三种方式:
1
方式一
手动单个设置
进入Properties属性后,需勾选Resolve to Simulink signal object
2
方式二
使用M语句实现
首先获得模型中的信号句柄,再对每条线的MustResolveToSignalObject属性设置为1:
set(find_system(gcs,'findall','on','Type','line'),'MustResolveToSignalObject',1)
取消绑定通过:
set(find_system(gcs,'findall','on','Type','line'),'MustResolveToSignalObject',0)
3
方式三
使用SimAssist工具快速进行关联
SimAssist具体功能和使用方法这里不做过多介绍,大家可参考如下网址:
https://note.youdao.com/share/index.html?id=a417ec0f08651694fb31928168bb010c&type=note#/
信号关联完成,即可进行代码生成工作,通过上述的配置,将会生成所要的条件编译代码,如下:
二、使用Variant Sink和Variant Source模块也可实现条件编译
其中实例1的条件编译代码也可用Variant Source模块实现,大家可以自行操练,下面介绍使用Variant Sink实现如下条件编译代码。
#if A
rtb_VM_Conditional_Signal_Sum_0 = x;
#endif
#if !A
rtb_VM_Conditional_Signal_Sum_0 = 0.0;
#endif
#if B
z = K1 * x;
#endif
根据如上代码建立如下模型:
同上,数据字典中创建三个信号变量x、y、z和三个参数变量K、K1和K2,然后将模型信号与数据字典相对应变量关联并生成代码:
条件编译在Simulink可通过多种方式实现,除了上面介绍的两种还有Variant Model等方式,不同的实现方法可应用于不同的场景,具体使用需根据具体情况自行选择。
参考文献
Mathworks官方文档
老胡的基于模型设计
Simulink仿真及代码生成技术