建模规范之解读MAAB5.0

MAAB规范的最早版本是在2001年推出的,那时RTW刚刚出现一年多,2007年4月出现2.0版。我最早接触的是2007年7月的2.1版,将2.1版实现自动检查后,对比后面2011年出现的2.2版及2012的3.0版,并没有发现大的变化,其内容一直局限于模型的接口界面及布局,对于模型的功能性、健壮性及代码优化方面没有涉及,因此总体感觉其重要性和Misra、HiSL、HISF等规范相比要低一些。5.0版本在2020年3月出现了,目前我们已经实现对这一版的自动检查并完成中文译本,在此过程中感觉和前三版有很大的不同,有必要和大家分享一下。

建立规范的目标

3.0及以前版本:针对模型的布局、可读性、可重用性及软件集成和软件交换

5.0:增加三个方面的内容

  • 仿真及验证—确保能够仿真,提高可测性
  • 代码生成—提高生成的代码在ROM及RAM的效率
  • 确保生成代码的健壮性

适用范围

3.0适用于Matlab 2007到2011,其后新版本的特性没有考虑在内

5.0适用于到目前的所有Matlab版本,对于和版本有关的规则,在条目中都做出了说明,并针对各个版本给出了具体的解决方法。

5.0版本中不包括模型运行时的错误问题并删除了3.0中大部分不能实现自动检查的规则,仅有很少的规则无法实现自动检查。

规范内容组织

5.0中每条规范均给出了详尽的说明、正反例及原因,方便实现自动检查。

在规范中有些给出了多种建议,实际应用中可以选择使用其中一种方式,如jm_0012中对于event的使用给出了三个建议,分别列为 a1 a2 a3:

命名规范

命名规范从3.0中的九条增加到20条,主要是可使用的字符及名称长度,列出了详尽的适用对象。命名长度统一规定为63个字符,但是由于windows路径及文件名称长度还是有260个字符的限制,及misra c的名称长度限制为31个字符,因此建议还是采用31或者更少的字符较为安全,并且一般情况下模块及变量名称等不会超过31个字符,规定为较短的长度才有自动检查的意义。

相比3.0,5.0中增加了如下内容

  • 在基本工作区,模型工作区及数据字典中的数据不能出现重名(在Matlab2019a以后,模型可以同时访问基本工作区,模型工作区及数据字典)。
  • 工作区及数据字典中不能存在未被使用的数据
  • 变量名称不能使用Matlab保留字

模型架构规范

5.0版中取消了架构部分中不能实现自动检查的规范,能够实现自动检查的规范被归到simulink及Stateflow部分,在规范后面部分增加了专门针对架构的章节,对架构设计中的一般原则做了阐述。

总结

MAAB5.0适用于至2020a为止的所有Matlab版本,包含的规范内容广泛,不仅包括模型接口界面及布局,还包括模块的安全使用、预防易出错的建模模式、提高可测性、模型优化等多方面的内容,实用性强、可自动化程度高。因此建议在构建企业规范时以MAAB5.0为基础,对于类似的规范,优先选择采用MAAB5.0中的定义,在此基础上选择其它规范中MAAB5.0所没有覆盖的内容。

对部分新增规范的解读

MAAB5中增加了许多全新的规范,在实现自动检查的过程中需要作出自己的解读,这里选择一部分和大家分享。

jc_0644:数据类型.

规范内容: 如果使用了Simulink.signal对象定义信号线的数据类型,就不要再在block及Stateflow chart中显式定义数据类型。

使用该规范的原因:如果在block中定义了数据类型,同时使用Simulink.Signal对象定义信号线的属性,在二者不一致时无法发现哪一个是正确的定义。

在模型中如果block中的数据类型和Simulik.Signal对象的不一致,则模型无法编译及仿真。

作为自动更正方法,考虑两种方式:

  1. 修改源block的输出数据类型为inherit: Inherit via back propagation, 或者Inherit: auto.
  2. 保留源block的设置,设置信号线的属性MustResolveToSignalObject为off。

由于两种方法都会造成模型已有信息的损失,在修改之前需要给出明确警示信息。

我们建议使用方法1对模型进行修改,保留Simulink.Signal对象。因为Simulink.Signal对象可以集中保存在脚本文件或者数据字典中,改动相对容易,而block中的设置是分散设置,修改时容易造成遗漏。在我们实现的检查中两种方法都可以使用,只需要通过参数进行选择。

规范定义中给出了下面1的情况:
1.block之间相连的情况,在block In3 In4及Sum1中定义了输出信号数据类型,同时在这些block的输出信号线上使用了Simulink.Signal 对象。

该情况下,报出两个输入端口的输出信号线及sum block的输出信号线的问题。

在实际检测中,我们还考虑了如下几种情况:

2.Stateflow chart和信号线相连的情况

3.子系统的输出端口和信号线相连的情况

4.数据类型无法设置为inherit的block的情况

例如prelookup block的K端口,此端口的数据类型无法设置为 inherit:auto,因此需要考虑将此端口作为例外,修正模型时修改block中的设置,否则问题无法改正。

jc_0121, jc_0610: Sum block 和Product block的使用

规范内容:

  1. a, b 略
  2. c: 输入信号数量不能超过两个

使用该规范的原因:清晰定义操作顺序

dSpace的规范ds_0029也要求Sum和Product block的输入信号不能多于两个,但是其理由是为了控制操作过程中中间变量的数据类型,防止溢出的情况出现,并且只限定于使用定点数的block(浮点数不存在溢出问题)。防止溢出对于软件安全性来说应该具有更重要的意义,因此在需要的情况下,可以使用ds_0029,仅检查使用定点数的模块。

在实现自动检查的过程中除了考虑block的输入端口的数量,还需要考虑输入信号是数组的情况(如:输入信号为多于两个元素的数组,操作是对所有元素取和或者积的情况)。 

 jc_0624: 对Tapped Delay block 及Delay block的使用

规范内容:在需要保存多个时间步长的值时,使用Tapped Delay block将多步的值保存在一个数组中,使用Delay block保存第一步的值。

使用该规范的原因:提高可读性及代码效率。

例如,将图中的4个unit delay block

用下图中的Tapped delay block代替

实现自动检查时需要考虑属性numberDelays 为1 的Tapped Delay block 及属性DelayLength为1 的Delay block,把这些block当做unit delay block处理。在判断是否有共同连接的block时还需要考虑共同连接到子系统的情况,如下图中,虽然在这一层中是连接到共同的block  subsystem2,但是实际上这些block没有共同的目标block,因此不在检查范围内。

jc_0640:条件执行子系统的初始值

规范内容:条件子系统满足下面两个条件时:

  • 包含具有初始值 (i.e. [Constant],[Delay])的模块。
  • 连接到 [Outport]。

初始值应在[Outport]中定义。当条件子系统的输出信号连接到Merge时,应在Merge中定义。

使用该规范的原因:当初始值不明确时,模型可能有非预期的行为。

实现自动检查时需要考虑将for iterator 及while iterator 子系统也作为条件执行子系统处理,因为这类子系统也需要初始值。

规范中规定的先决条件是outport和具有初始条件的block相连,而dSpace的规范ds_0018中没有此先决条件,无此先决条件会使建模风格一致性及软件安全性更好,因此我们提供了选项,可以通过参数设置采用或者忽略此条件。

0751:状态转移中的回溯预防

规范内容:不要使用连接节点分割复杂条件。

使用该规范的原因:避免回溯情况的出现,回溯可能会导致意外结果。

回溯是Stateflow的一种机制,应尽量避免使用。此条规范的定义比较笼统,仅根据这些描述及提供的例子无法实现自动检查。由于此规范的目的是预防回溯的出现,我们参考Misra_slsf_043中H部分的定义实现了自动检查,其不通过的条件如下:

  • 转移T1是有条件转移
  • T1的源是节点J1
  • 节点J1包含至少一个以J1为目标的条件转移T
  • 转移T是缺省转移或者
  • T的源中的一个是节点,并且此节点包含多于一个以此节点为源的转移;或者T的源中的一个是State

另个,如果一个节点只有一个输入转移及一个输出转移,并且都是条件转移,也给出不通过的结果。

另外,模型参数Diagnostics->Stateflow->unexpected backtracking对于发现回溯也是帮助的,因此我们也检查该参数是否被设置为“Error“。

0763:多个内部转移的使用

规范内容:

a1:在单个状态中不要使用多个内部转移。

a2:在单个状态中的多个内部转移应该按照执行顺序从上到下排列。

使用该规范的原因:

此条规范是目前的公共规范中首次出现的针对内部转移的规范。实现该规范的自动检查并不困难,在实现该规范过程中,我们发现无条件的内部转移会带来死代码, 如下图,状态A3无法到达。

仿真时的执行顺序如下:

time 0
A1 en:x=1; default transition-> A2, A2 en: x+=10;

time 1
A1 du: x+=3; 内部转移 x+=2; A2 en:x+=10

time 2
A2 du: x+=3; 内部转移 x+=2; A2 en:x+=10

time 3
A2 du: x+=3; 内部转移 x+=2; A2 en:x+=10

在内部转移中增加条件,则在条件不成立时,从A2转移到状态A3,如下图。

为此我们建立了一条规范来避免上述情况的出现,并实现了自动检查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值