Matlab/RTW EC面向MC9S12D64的自动代码生成
2014-09-06杨润泽
杨润泽
(湖北汽车工业学院 汽车工程学院,十堰 442002)
Matlab/RTW EC面向MC9S12D64的自动代码生成
杨润泽
(湖北汽车工业学院 汽车工程学院,十堰 442002)
传统的电控软件开发模式已无法满足日益庞大、复杂的汽车电控系统的开发要求,基于模型的开发方法以及自动代码生成技术在汽车嵌入式软件开发中得到越来越广泛的应用。本文介绍使用Matlab/Real-Time Workshop Embedded Coder(Matlab/RTW EC)将Simulink控制模型生成C代码以及生成代码与Freescale MC9S12D64单片机底层代码的集成方法,通过测试验证了生成代码的有效性。
嵌入式系统;基于模型设计;代码生成;RTW EC
引 言
随着汽车电子控制系统的日益复杂化,以及用户对产品安全性、可靠性的要求,嵌入式应用的开发难度与代码量都在迅速增加。目前,一台中高档汽车的软件控制代码就超过了500万行,通用雪佛兰Volt整车的代码量超过1 000 万行,而一辆功能先进的医疗急救车甚至需要超过5 000万行的软件代码,而且随着设计内容的增加、多变的新特征、模糊的设计参数以及用户不断增加的需求,程序员的劳动量大大增加,传统的手工编程方式越来越不能适应现代汽车电控系统的设计开发要求[1-2]。
Matlab/Real-Time Workshop Embedded Coder(Matlab/RTW EC)是MathWorks公司提供的嵌入式代码自动生成工具,它能够快速地将Matlab/Simulink控制器模型自动生成优化的、可移植的产品级C代码,并根据特定的目标配置自动生成嵌入式系统实时应用程序,从而大大减轻软件工程师的工作量,缩短嵌入式系统的开发周期,提高开发效率。本文以Freescale MC9S12D64单片机为目标芯片,说明从Simulink控制模型生成目标嵌入式代码的方法。
1 基于模型的设计
基于模型的设计是利用计算机建模仿真技术,快速完成嵌入式产品等产品开发过程中核心算法的开发和验证工作,利用自动代码生成技术快速完成产品开发中的逻辑功能、处理算法的实现,同时利用模型的方法构造出被控对象,方便、快捷、大量重复地进行产品控制效果的验证工作。相比于传统的开发模式,基于模型的设计开发流程具有以下一些优点[3-4]:
① 在统一的开发测试平台上,让设计从需求分析阶段就开始验证与确认,并做到持续不断地验证与测试,让设计的缺陷尽量暴露在开发的初级阶段。
② 让工程师把主要精力放在算法和测试用例的研究上,嵌入式C代码的生成与验证留给计算机去自动完成。
③ 模型的复用性好,易于维护和移植。
④ 大大缩短开发周期并降低开发成本。
图1为基于模型的设计开发流程。在基于模型的设计方法中,系统工程师首先要建立一个系统模型来精确、无歧义地描述用户的需求,创建一个可执行、可跟踪的技术规范,并在系统模型与需求之间建立双向链接。在整个开发过程中,工程师利用测试用例追踪系统级模型和需求,了解系统模型的功能覆盖度。这些测试通常包括以下三种:
① 软件在环测试(Software-in-the-Loop, SIL)是对模型生成的代码或者手写代码进行非实时仿真,目的是为了验证生成的代码和模型在功能上的等效性。
② 处理器在环测试(Processor-in-the-Loop, PIL)是将自动生成的C代码下载到目标处理器中,与被控对象一起进行非实时的联合仿真,目的是为了测量模型生成的代码在目标处理器上的运行时间,即检查运行速度和资源消耗。
③ 硬件在环测试(Hardware-in-the-Loop, HIL)是把被控对象的模型生成C代码并编译成可执行的文件放到工控机上运行,然后把控制器和工控机通过线束连接,实现闭环控制,检查整个系统功能。
图1 基于模型的设计开发流程[5]
显然,算法的实现是联系系统模型和在环测试验证的重要纽带,这其中所涉及的代码自动生成技术是基于模型开发方法的关键技术之一。自动代码生成的基本流程包括[5]:运行Model Advisor进行模型检查、配置代码生成选项、生成代码、检查生成的代码及报告以及测试生成的代码等5个环节。
生成代码的过程如图2所示。用户在Matlab/Simulink/Stateflow建立的算法模型经过Simulink编译器生成rtw中间文件;rtw文件是一个描述整个模型的结构体文本,包含模型中的参数、变量、模块名称以及为代码生成所做的各种配置,rtw文件经过目标语言编译器(Target Language Compiler, TLC)生成C语言代码,最后通过C编译器得到最终的可执行程序[1,6]。
图2 Matlab/RTW EC代码自动生成过程[7]
2 流水灯模型建立及嵌入式代码生成
流水灯Simulink功能验证模型,通过设置脉冲发生函数的周期和占空比,使LED灯按照一定的时间间隔顺时针方向轮流点亮。示意图略——编者注。
将流水灯功能验证模型中的脉冲生成器和Goto模块分别使用In、Out模块替换后得到的自动代码生成模型如图3所示。
图3 代码生成模型
在Configuration Parameters中对代码生成过程进行相关的配置并指定变量的数据类型后,Matlab/RTW EC依据上述的流水灯控制模型自动生成了ert_main.c、LightsCtr.c、LightsCtr.h、LightsCtr _private.h、LightsCtr _types.h、LightsCtr _private.h、rtwtypes.h等6个文件。其中,ert_main.c提供了算法函数调用的样例程序,它包括main()、rt_OneStep()函数。LightsCtr.c包含了LightsCtr _initialize()、LightsCtr _step()、LightsCtr _terminate()函数,是整个模型的算法实现代码。
3 应用层底层代码集成
Matlab/RTW EC生成的应用层代码和特定芯片的驱动代码集成目前主要有两种方式:一种方式是在建模过程中,将驱动程序封装为S函数模块,代码自动生成的过程中建立相应芯片的TLC模板文件,实现一键从模型到编译代码下载到控制器芯片中。第二种方式是在集成开发环境(Integrated Development Environment, IDE)中手工进行代码集成。
在产品化的项目开发中,采用第一种方式集成代码,需要对底层驱动建模,存在以下的困难:①底层驱动在Simulink环境下不能仿真;②底层驱动建模需要熟悉TLC脚本语言;③产品化项目的底层软件往往很大,开发一个安全、可靠的底层模块库,针对特定的目标板定制TLC文件等,都需要大量的时间投入,不易操作。
从项目开发的角度考虑,一般的项目多是采用第二种方式,也就是先进行产品化代码生成然后手工进行代码集成,节省了“目标板模型化”的成本和时间,有利于项目代码文件的管理与维护,而且问题追溯和代码调整也更为方便和灵活。
基于上述考虑,本文采用将自动生成的代码在CodeWarrior中进行手工代码集成,在ert_main.c中添加必要的与硬件相关的代码,例如头文件、中断服务程序、硬件初始化代码、算法与硬件接口代码、循环语句等。集成后的ert_main.c源代码如下:
……
#include
#include "LightsCtr.h" /* Model's header file */
#include "rtwtypes.h" /* MathWorks types */
#include
#include "derivative.h" /* 添加头文件*/
……
long flag=0; //中断发生标志
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 26 void Timer_ISR(void){ //中断服务程序
flag++;
MCCNT=0xFFFF;
MCCTL_FLMC=1;
MCFLG_MCZF=1;
}
#pragma CODE_SEG DEFAULT
……
void rt_OneStep(void){
……
/* Re-enable timer or interrupt here */
EnableInterrupts; //允许可屏蔽中断
……
/* Get model outputs here */
PORTA_BIT7=LightsCtr_Y.Out1;//输出与硬件端口关联
PORTA_BIT6=LightsCtr_Y.Out2;
PORTA_BIT5=LightsCtr_Y.Out3;
PORTA_BIT4=LightsCtr_Y.Out4;
PORTA_BIT3=LightsCtr_Y.Out5;
PORTA_BIT2=LightsCtr_Y.Out6;
PTM_PTM7=LightsCtr_Y.Out7;
PORTB_BIT2=LightsCtr_Y.Out8;
PORTB_BIT0=LightsCtr_Y.Out9;
PORTK_BIT7=LightsCtr_Y.Out10;
PORTE_BIT2=LightsCtr_Y.Out11;
PORTE_BIT3=LightsCtr_Y.Out12;
……
}
int_T main(int_T argc, const char_T *argv[]){
/* Initialize model */
LightsCtr_initialize();
MCCTL=0xC7;//允许中断,模数计数方式和分频常数设置
MCCNT=0xFFFF;
MCCTL_FLMC=1;
DDRA=0xFC; //设置输出端口
DDRM=0x80;
DDRB=0x05;
DDRK=0x80;
DDRE=0x0C;
……
//删除printf和fflush代码
while (rtmGetErrorStatus(LightsCtr_M) == (NULL)) {
/* Perform other application tasks here */
if(flag==1) {
flag=0;
LightsCtr_U.In1=~LightsCtr_U.In1;
//翻转输入信号,实现脉冲输入
}
rt_OneStep();
}
……
}
将集成后的代码通过inDART-one在我校开发的汽车电子技术实验系统上进行了测试,实现了预期LED灯顺时针明灯流动,验证了整个开发流程的可行性。
结 语
本文建立了LED流水灯的Simulink控制模型,使用Matlab/RTW EC将该控制模型生成嵌入式C代码,并将自动生成的C代码与Freescale MC9S12D64单片机底层代码进行了集成和测试,得到了预期的LED灯控制效果。这种基于模型的开发方式以及自动代码生成技术使得控制算法具有更高的可移植性、更快的开发迭代速度,从而能够大大地提升电子控制系统的开发效率,降低开发成本。
Yang Runze
(School of Automotive Engineering, Hubei University of Automotive Technology, Shiyan 442002, China)
Tranditional electronic control software development mode can not meet the requirements of increasingly huge and complex automotive electronic control systems. Model-based design associated with automatic code generation is more and more widely used in the development of vechicle embedded software. This paper presents the method for converting Simulink control model to C codes with Matlab/Real-Time Workshop Embedded Coder (Matlab/RTW EC) and integrating the generated codes with low-level codes of Freescale MC9S12D64 microcontroller. Further more, the validation of generated codes is verified by testing.
embedded system; model-based design; code generation; RTW EC
TP368.1
A