李延红,张书朋,李 成
(中国重型汽车集团有限公司技术发展中心,山东 济南 250101)
在汽车嵌入式软件V模式开发中,应用层代码一般会采用基于模型的开发 (Model-Based Development,MBD)模式实现。即利用美国迈斯沃克 (MathWorks)公司研发的工业标准建模工具MATLAB建立算法模型,经过浮点模型和定点模型测试完成后,会通过自动生成代码工具Embedded coder自动生成代码。本文对基于模型的开发MBD模式中大量重复性操作工作效率低问题,进行自动化脚本工具开发,并通过发动机后处理控制算法模型进行脚本工具应用验证。1 基于MBD软件开发
随着汽车嵌入式软件复杂程度的增加、系统开发周期的逐渐缩短,基于MBD软件开发模式逐渐替代传统C代码开发方式。基于MBD软件开发模式可以用建模工具对复杂逻辑进行设计,使得系统需求分析与软硬件开发结合更加紧密,系统分析可以直接与设计结合;在软件开发仿真开始,开发人员就可以调试逻辑,加快调试进度;可以自动生成代码,避免手工编码方式可能存在的低级错误;模型建立后,可利用快速原型仿真,加快需求设计完善;模型可移植性高,可迅速建立系统设计模块库,节约开发成本。
基于MBD软件开发流程,开发汽车嵌入式软件依次经过系统设计、模型设计、C代码生成编译、硬件代码生成调试、硬件在环、实车测试6个步骤。在实车测试之前,模型设计阶段完成之后,会对应系统功能设计进行MIL(model in the loop,模型在环)测试,从模型仿真阶段验证模型功能实现满足系统功能定义;C代码生成编译阶段完成后,会对应模型设计进行SIL(software in the loop,代码在环)测试,从代码阶段验证模型与生成代码功能一致性;硬件代码生成调试阶段完成后,会对应C代码生成编译阶段进行PIL(processor in the loop,处理器在环)测试,验证模型与运行在目标处理器上的代码功能一致性;硬件在环阶段,会对应系统功能定义进行HIL(hardware in the loop,硬件在环)测试,用物理模型控制器和控制模型控制器联合验证是否满足系统功能定义。基于MBD开发流程如图1所示。
由图1可见,基于MBD开发嵌入式软件时,基于系统功能定义准确搭建模型、保证代码生成与模型一致性是关键。由于要达到准确搭建模型、保证代码与模型一致,要求按照MBD开发流程进行大量重复性操作,因此有必要进行模型开发自动化脚本工具开发,以便提高工作效率。
图1 基于MBD软件开发流程
基于MBD流程进行嵌入式软件模型开发时,一般经过浮点模型搭建、浮点模型规范化、浮点模型测试、浮点模型多模型检查、定点模型搭建、定点模型规范化、定点模型测试、定点模型多模型检查、代码生成、代码测试、代码集成11个步骤。基于MBD模型开发流程如图2所示。
1)步骤1:浮点模型搭建
首先根据系统功能定义进行浮点double数据类型模型搭建,模型复杂程度随着功能不同而不同。汽车嵌入式软件开发中一般会遵循MISRA C规范,规范要求模块使用和模型可视两方面。规范使用Simulink模块在搭建过程中可以通过使用模型库来提高效率,由于模块库会不断更新,因此在搭建模型时需要使用最新版本模块库。规范模型可视化对应到Simulink中搭建模型时需要将模型分层、信号线上需要显示信号名称、信号线需要对齐。由于模型分层会造成不同层子系统之间输入输出口需要手动连接,还会造成连接后的信号线凌乱。
浮点模型搭建过程自动化需求为:模块库版本确认、悬空的输入输出口信号线连接、输入输出口信号线对齐、模型顶层信号线上添加变量名称、非模型顶层信号线上添加信号继承标志以显示信号变量名称、删除冗余变量。
2)步骤2:浮点模型规范化检查
浮点模型规范化检查采用Simulink工具Model Advisor来实现。由于Simulink工具Model Advisor检查涵盖的规范较广,开发人员很难确定检查项。
浮点模型规范化检查过程自动化需求为:自动调用Model Advisor和自动选择符合本项目要求的检查项来检查模型规范符合度。
3)步骤3:浮点模型测试
浮点模型测试过程中会首先用Simulink工具Simulink Design Verifier进行形式检查,然后用Simulink工具Simulink Test进行功能验证。由于测试会根据结果反复,需要多次手动打开测试工具,在功能验证阶段多次手动导入测试用例及测试结果。
图2 基于MBD模型开发流程
在浮点模型测试过程自动化需求为:自动调用Simulink Design Verifier对模型进行形式化检查、自动调用Simulink Test搭建测试模型、导入测试用例、运行及保存测试结果。
4)步骤4:浮点模型多模型检查
浮点模型多模型检查主要是核对接口信号是否存在遗漏或者重复的情况。
在浮点模型多模型检查过程自动化需求为:批量提取模型接口信号名称、核对接口信号来源及去处、检查所有模型中全局系统常数数值冲突。
5)步骤5:定点模型搭建
由于浮点模型均是double类型,生成代码占用空间大且执行效率低,因此在保证代码效率、数据精度和数据范围前提下需要将浮点模型转换为定点模型。浮点模型转换为定点模型过程中需要对每个信号及模块定标,工作繁琐且容易产生错误。
定点模型搭建过程自动化需求为:建立数据对象、关联数据字典和模型中的数据对象、定标整数常数模块为最短长度的整型类型、自动定标输出线上有测量变量的模块为“向后继承”属性、将子系统设置为原子子系统。
6)步骤6:定点模型规范化
定点模型规范化检查主要分为用Simulink工具Model Advisor来实现定点部分检查以及定标合理性检查。
定点模型规范化过程自动化需求为:自动调用Model Advisor检查、顶层输入必须有信号且关联、减法输出类型设定不为无符号数、数据类型为浮点或超过32位。
7)步骤7:定点模型测试
定点测试方法与浮点测试相同,测试结果要与浮点测试结果对比以便核对定点过程中的精度损失是否在允许范围内。
在定点模型测试过程自动化需求为:自动调用Simulink Design Verifier进行形式化检查、自动调用Simulink Test进行功能测试、进行定点模型和浮点模型测试结果对比。
8)步骤8:定点模型多模型检查
定点模型多模型检查主要是核对接口信号及全局系统常数是否存在数据类型冲突。
定点模型多模型检查过程自动化需求为:批量提取模型接口信号名称、核对接口信号数据类型、检查全局系统常数数据类型。
9)步骤9:代码生成
代码生成通过Simulink工具Embedder Coder来实现,不同经验开发人员单独使用代码生成工具时花费时间不同,造成开发周期增长;自动生成的代码中包含全局变量的定义和声明,导致全局变量会重复定义和声明;自动生成的代码会自动放置在模型所在文件夹下新建‘模型名_ert_rtw’文件夹,导致集成时读取不方便。
代码生成过程自动化需求为:自动调用自动生成代码模板配置批量生成代码、将所有模型生成代码放到一个文件夹。
10)步骤10:代码测试
代码测试通过SIL进行,即将模型自动生成的C代码封装为可以在MATLAB环境中执行的S函数模块,代替定点模型进行测试。
代码测试过程自动化需求为:自动调用SIL测试,进行SIL测试和定点模型测试结果对比。
11)步骤11:代码集成
代码集成是将生成代码放置在代码编译环境中集成,手动操作容易造成版本失误。
代码集成过程自动化需求为:生成全局系统常数声明文件、自动生成A2L文件。
MALTAB自带的M语言采用解释执行的方式,继承了计算、可视化以及数据表达式相似的编程环境,降低编程所需难度并节省时间。M语言提供的函数能够控制模型仿真、获取和设置模型及模块的属性,还支持模型的打开、关闭、保存以及模块的拷贝、移动、删除及信号线的连接和断开。
本文采用M语言编写各功能函数,通过GUI可视化界面函数调用的方式实现。
1)建模辅助脚本GUI可视化界面
自动化工具可读性非常重要,本文利用GUI制作了自动化工具运行可视化界面。按照MBD开发过程中自动化需求逐条体现在界面以checkbox形式显示,运行界面图如图3所示。MBD开发单个功能模型时,运用本自动化工具需要先将模型打开。然后按照自动化需求勾选check box,点击pushbutton属性运行按钮即可完成自动化操作。
图3 建模辅助脚本工具运行界面图
开发时首先通过guide命令创建空GUI界面,然后将每条自动化需求以checkbox形式进行界面设计,实现时是pushbutton属性运行按钮回调函数调用功能函数来实现,实现代码如图4所示。
2)自动化功能函数
M语言提供的函数可以控制模型仿真,获取和设置模型、模块的属性等功能,自动化功能函数是利用M语言本身提供的函数获取功能自动化对象,然后增加判断逻辑实现。
图4 自动化工具调用自动化需求功能函数代码示例
浮点模型搭建过程中自动化需求均是对模型中的Simulink模块的属性进行修改,基本采用find_system、get_param、set_param函数来实现。用find_system函数来找到要自动化实现的模块路径或句柄,用get_param获取自动化模块名或者属性,用set_param函数来实现模块参数设置。自动化需求模型顶层信号线增加变量名称代码如图5所示。
图5 模型顶层信号线增加变量名称代码示例图
浮点模型规范化检查是针对自动调用Model Advisor工具来实现的,用ModelAdvisor工具中函数来实现,如ModelAdvisor.Run为运行Model Advisor工具,图6为自动调用Model Advisor工具代码示例图。
图6 自动调用Model Advisor工具代码示例图
浮点模型测试是自动调用Simulink工具Simulink Design Verifier和Simulink工具Simulink Test。自动调用Simulink工具Simulink Design Verifier直接采用sldvrun函数来实现,Simulink工具Simulink Test工具调用采用sltest.harness.create函数来创建测试模型,导入测试用例进行测试。
浮点模型多模型检查实现时首先用find_sysytem函数提取找到各个子模块输入输出变量和全局系统常数,然后用strcmp函数对比较输入输出来源及系统常数数值。
定点模型搭建过程中的建立数据对象时是利用mpt.Signal函数和mpt.Parameter函数来创建,代码示例可见图7。数据对象关联、自动定标整数、自动定标为向后继承及设置为原子子系统均是对模型或者模块进行设置,基本采用find_system、get_param、set_param函数来实现。
定点模型规范化实现自动调用Model Advisor检查时代码基本与浮点模型规范化代码一致,设置CheckIDList来实现不同测试配置。
顶层输入信号关联、减法输出类型设定不为无符号数、数据类型为浮点或超过32位判断可通过find_sysytem函数及strcmp函数来实现。
定点模型测试测试实现与浮点模型测试实现代码基本一致,实现定点模型和浮点模型测试结果对比通过strcmp函数来实现。
定点模型多模型检查实现与浮点模型多模型检查实现代码基本一致,通过find_sysytem函数及strcmp函数来实现。
代码生成过程自动调用自动生成代码模板配置批量生成代码实现时是首先用open函数打开第一个模型,然后对该模型进行生成代码配置及生成代码,保存,然后再打开下一个模型直至结束。单独模型生成代码配置及生成代码实现代码示例如图8所示。
图7 建立数据对象代码示例
图8 单独模型生成代码配置及生成代码实现代码示例
将所有模型生成代码放到一个文件夹是依次循环将所有模型生成代码文件放到一个文件夹,单个模型生成代码放到一个文件夹代码实现示例如图9所示。
图9 单个模型生成代码放到一个文件夹代码实现示例
代码测试过程实现调用SIL测试,进行SIL测试和定点模型测试结果对比时首先创建测试模型,然后进行正常测试和SIL测试,最后进行结果对比。示例代码如图10所示。
图10 SIL测试实现代码示例
代码集成过程实现生成全局系统常数声明文件时与生成数据对象代码基本一致,使用mpt.Parameter来实现。自动生成A2L文件是将自动生成代码中单独子模块生成的A2L文件组成为一个A2L文件,删去重复生成的变量,并利用编译代码生成的MAP文件进行地址替换。在替换地址时首先要进行变量识别,识别过程采用正则表达式实现。识别标定量正则表达式部分代码示例如图11所示。
图11 识别标定量正则表达式代码示例
以某型发动机后处理再生开关故障判断模型为例,由于正常情况下后处理再生开关按下之后10s之内会自动弹起,当后处理再生开关按下状态持续大于20s则认为后处理再生开关处于按下卡滞状态。当发动机后处理再生开关处于按下卡滞状态时,会导致再生请求一直存在,发动机后处理颗粒捕集器存在烧熔的风险。
按照功能定义手工搭建模型如图12所示。
图12 手工搭建浮点原始模型
从图12可见,该模块使用了模块库,但是明显不是最新版本模块库,输入输出口信号凌乱、信号线上无变量名。
运行自动化脚本工具勾选项如图13所示,点击运行模型变化为图14所示。
图13 浮点功能建模自动化工具运行界面
由图14可见,执行完自动化操作后,模型替换为最新版本模块库,输入输出口信号整齐,信号线上添加了变量名,模型封装为子系统且子系统变量名默认取模型名。当存在多个子系统时模型名后依次加序号区别。
本文针对MBD模式开发过程中大量重复性工作导致的效率低问题进行开发自动化脚本工具,采用MATLAB/M语言来实现。本文的MBD软件开发自动化脚本工具提高了开发人员工作效率,降低了对开发人员针对MBD开发模式的专业程度,细节化操作选项灵活组合提高了脚本复用率。该自动化脚本工具开发方法为同领域嵌入式软件自动化开发提供了借鉴参考。
图14 浮点功能建模自动化执行后模型图