基于Simulink自动代码生成技术的CAN底层模块库设计
2020-08-03莫官旭谢勇波王文明
汪 伟,莫官旭,申 健,谢勇波,王文明
(长沙中车智驭新能源科技有限公司, 湖南 长沙 410036)
0 引言
汽车控制器之间的通信主要通过CAN(controller area network)总线实现。随着汽车功能的不断丰富,控制器数量逐渐增多,CAN报文信息交互频繁,所需处理的数据越来越多;而传统软件开发方式存在开发时间长、代码量大、易出错和不易扩展的不足。另外,在基于模型设计[1-2]的软件开发中,模型生成代码的变量不便与CAN底层函数的参数关联,需将模型生成代码中的变量一一赋值至手写代码的底层函数中使用。
基于模型的设计是嵌入式软件快速开发的一种方式,在Simulink环境下使用模块库搭建控制策略模型,使用RTW(real-time workshop)将模型生成代码,再编译烧写到嵌入式控制器中运行。相比编辑C代码的嵌入式软件开发方式,基于模型的设计可视性更高、移植性更强,并且可在Simulink上对逻辑进行仿真,简化测试工作。若通过Simulink模块实现CAN报文收发、装载与解析功能,则能有效提高开发效率和代码可靠性,增强软件移植性[3-4]。据此,本文使用Simulink的S函数(S-Function)并编写相应的M语言脚本和由目标语言编译器(target language compiler, TLC)转换的TLC文件,设计了一种基于自动代码生成技术的CAN底层模块库,用于实现控制器的CAN通道初始化和CAN报文的接收与发送、解析与装载。
1 模块功能设计
在Simulink环境中,需要设计S-Function和与之关联的TLC文件,以达到生成自定义格式代码的目的[5-7]。首先,在Matlab中编辑M语言脚本并在模块中调用,用于处理传入模块的数据和设置显示在模块上的字符;然后,在TLC文件中对这些数据如何生成代码以及所需包含的头文件进行描述,从而在生成的C代码中调用控制器底层函数,其原理如图1所示。
图1 S-Function生成自定义代码原理图Fig. 1 Principle diagram of S-Function custom code
本文使用的TC21x芯片平台控制板的CAN通信C语言底层函数包含的功能有:硬件CAN通道设置、发送CAN报文及配置接收报文,函数名和所需设置的形参如图2所示。
图2 C语言底层函数Fig. 2 C language underlying functions
根据C语言的底层函数和Matlab支持读取DBC(database for CAN)文件的功能,将CAN底层模块库划分为CAN初始化、CAN报文数据装载与发送、CAN报文数据接收与解析这3种功能S-Function模块。CAN初始化模块用于设置波特率和工作模式,其他两个模块用于读取导入模型的DBC文件信息,并调用CAN报文收发底层函数来实现对报文数据的处理与收发。根据底层函数所需传入的参数类型,3个模块的功能结构设计如图3所示。
图3 自建CAN底层模块库功能结构Fig. 3 Functional structure of self-building CAN communication library
2 功能实现
CAN底层模块库的各个模型均需图形用户界面(graphical user interface, GUI)与数据处理功能。在GUI的设计上,Matlab/Simulink提供了便捷的Mask Editor和GUIDE工具供使用者对Simulink模型进行封装,可将各模块所需传入的参数类型作为模块对话框的输入项,并为GUI上的控件添加回调函数,对输入数据进行处理,最终传入S-Function参数用于生成代码。
CAN初始化所需输入的参数信息较少,可使用Mask Editor对硬件CAN通道编号,将波特率和工作模式设置为弹出式下拉菜单,并为每个控件对应的Name属性命名,以此作为S-Function中S-function parameters的输入参数名称。实现CAN初始化模块同名的TLC文件后,可生成代码。所设计的对话框和所生成的代码如图4所示。
图4 CAN初始化模块的对话框界面与所生成的代码Fig. 4 Dialog interface and generated code of CAN initial block
CAN报文装载与发送、CAN报文接收与解析输入模块参数较多,用GUIDE设计对话框界面可以显示更丰富的内容。为了方便观察模块所使用的CAN报文中每个信号的信息,用GUIDE将CAN报文信息的变量名、起始位、信号数据长度、比例系数及偏移量根据起始位置排序,并以表格形式在模块的对话框中显示。报文信息来源于DBC文件,因此需为GUI的Browse和Message list编辑框对应的控件设置回调函数,用于选择指定路径的DBC文件,并在选择所需报文ID后对协议内容进行读取与处理,之后再写入到模块参数中。以EEC1(ID为0x0CF00400)报文中的发动机转速信号为例,CAN报文装载与发送模块对话框与所生成的代码如图5所示。
图5 CAN报文装载与发送模块的界面与代码Fig. 5 Dialog and generated code of CAN message loading and sending block
为了便于在同一模型工程中对不同设置参数的模块进行区分,可通过 Mask Editor中的Icon drawing commands设置模块外观显示的符号与文字。将CAN接收与解析模块进一步细分为带回调函数功能的模块和不带回调函数功能的模块,以满足不同需求。CAN底层模块库各模块封装效果如图6所示,从左至右、从上至下分别为CAN初始化模块、CAN报文装载与发送模块、CAN报文接收与解析模块以及带回调功能的CAN报文接收与解析模块。
图6 CAN底层模块库各模块封装效果Fig. 6 Encapsulation effect of each block in the CAN underlying module library
完成各模块的功能实现、封装和属性设置后,可将各模块集成为Simulink模块库。编写与模块库对应的slblocks.m文件,将该文件与模块库文件所在路径添加到Matlab的工作路径列表中。在Simulink Library Browser中执行Refresh操作,CAN通信模块库可显示在Simulink库浏览菜单中,以便查找和使用,效果如图7所示。搭建模型时,只需在CAN底层模块库中将相应功能的模块拖入到.mdl或.slx模型文件中即可。每个在工程中使用的模块与CAN底层模块库中的父模块存在关联关系;在后期软件维护时,只需对模块库中的父模块功能进行修改,即可改变整个模型文件中各CAN模块的功能与生成代码的格式。
图7 CAN通信模块在Simulink Library Browser中显示效果Fig. 7 Display effect of CAN communication block in Simulink Library Browser
3 功能验证
在完成了CAN通信模块库的功能设计与封装后,为了验证CAN模块是否能在硬件平台上正常运行,本文在Infineon的TC21x系列控制板上试验CAN报文的发送与接收功能。试验环境结构如图8所示。
图8 试验环境组成Fig. 8 Test environment composition
本次试验分别用EEC1报文中的发动机转速值和TCO1(ID为0x0CFE6CEE)报文中的整车车速值作为报文接收解析和报文数据装载与发送的测试对象。其中,发动机转速值在EEC1的BYTE4和BYTE5位置,分辨率为0.125 (r/min)/bit;整车车速值在TCO1的BYTE7和BYTE8位置,分辨率为1/256 (km/h)/bit。搭建如图9所示测试模型,其中,CAN初始化模块和CAN报文装载与发送模块分别被置于Simulink的原子子系统,用于指定函数名、生成单独的C函数以区分不同的模块功能,方便调用。使用Simulink编译模型验证了使用模块库所搭建的模型能成功生成代码,各子系统内部如图10所示。
图9 测试模型Fig. 9 Test model
图10 测试模型子系统内部Fig. 10 Inner of the test model subsystem
将生成的C代码函数加入整个软件工程中调用,编译后烧写到控制器内;使用上位机软件CANTest对TCO1的报文情况进行采集,模型中车速的设置值为45,报文发送值为0x2D00(对应的十进制值为11520),如图11所示,根据协议解析可得实际值为45 km/h。
图11 报文采集结果Fig. 11 Result of message collecting
在CANTest的基本操作栏中,设置报文帧ID和数据值发送给控制板,如图12所示。本文设置EEC1的发动机转速报文原始值为0x1450(十进制值为5200,根据协议,解析值为650 r/min),通过控制板的上位机监控板可得所接收的内容为650,如图13所示。
图12 模拟发送报文Fig. 12 Simulated message sending
图13 上位机监控板接收到的发动机转速值Fig. 13 Speed value of engine in the upper computer monitoring board
通过以上测试结果可看出,自建的CAN底层模块库接收与解析功能、数据装载与发送功能能在控制板中能正常运行,且协议解析内容与DBC文件中设置内容相符。
4 结语
本文通过Simulink自建CAN底层模块库,在Infineon控制板上实现了对数据发送和接收功能底层函数的调用,并将DBC文件的信息导入到模块中;结合控制板已实现的C语言底层函数,分别建立CAN报文接收与解析、CAN报文装载与发送功能模块;通过Simulink自动生成代码技术验证了自建模块库所生成的代码在控制器上的运行结果。在基于TC21x系列芯片控制板的试验环境中的测试结果表明:自建的CAN底层模块库可正常调用底层的CAN报文发送和接收函数功能,并能解析报文或根据协议装载成原始报文。使用该方法,不需要人为对照CAN协议来编辑C代码和对CAN报文解析与装载,模型会自动根据DBC文件来对CAN报文信息进行处理,相比传统软件开发,降低了编写软件时对照报文协议的错误率,节省了开发时间,方便后期维护工作。由于本文模块库在代码中生成了较多单精度或双精度型变量,这会占用较多的控制板数据存储空间,因此优化生成代码中的数据类型是本文方案需要改进之处。