来源:乔美昀 , 韦天文/上汽通用五菱汽车股份有限公司随着现代汽气车上集成的ECU越来越多,整车网络戒来越复杂。诊断通信作为车载网络中的一个重要功能,开发周期和难度也不断增加。为了提高软件的复用率和可移植性,缩短开发周期,全球汽车制造商、零部件供应商、半导体供应商及工具供应商共同制定了 AUTOSAR标准。AUTOSAR标准的核心是剥离 ECU 软件开发对硬件的依赖,为此它将软件分为应用层软件组件(SW Component)、基础软件包(Basic Software)和运行时环境(RTE),AUTOSAR标准如图1所示。本文在深入研究 AUTOSAR标准的设计思想和软件体系后,参照AUTOSAR 标准街推荐的诊断通信架构,开发了一个基于CAN 总线的、具有通用性和可移植性的诊断通信协议栈。为了实现网络通信系统开发的标准化,国际标准组织(ISO)制定了 OSI模型。这个模型把网络通信分为7个工作层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。ISO在后来制定的诊断通信协议中,如 ISO15765、ISO14229、ISO15031,也按照 OS模型对诊断通信进行了分层,并用具体的诊断通信协议对每层做了详细的规定。随着诊断通信协议的不断完善,已经形成一套完整的诊断通信架构(见表 1)。根据应用范围的不同,诊断通信分为2种∶ 一种是与排放无关的诊断,叫增强型诊断,即UDS诊断;一种是与排放相关的诊断,叫OBD诊断。传统的诊断通信协议栈的开发,基本都是按照诊断协议中OST模型来建立整体架构的。但诊断通信的OST模型并没有在具体功能的开发上提供参考,这就导致不同的汽车制造商按照各自的软件开发标准开发出各自专用的诊断通信软件,其中有的诊断通信软件在诊断应用层直接操作硬件,这些都造成汽车诊断通信软件缺乏通用性和可移植性。AUTOSAR 标准基于传统的OSI模型,为诊断通信软件的开发提供了一套完整的解决方案。协议栈的硬件平台根据选用的芯片、连接的方式及具体的布局而异,但根本原理都是一致的,CAN控制器是硬件的核心,通过不同的CAN收发器接到不同的CAN总线上。基础软件的微控制器抽象层主要解决硬件的底层驱动问题,对应在诊断通信协议栈中是CAN驱动层。当将诊断通信协议栈移植到其他硬件平台上,只需对 CAN 驱动做相应的更改,上层软件则可以完全复用。ECU抽象层,也叫硬件抽象层,主要解决上层软件和硬件驱动之间的接口问题,对应在诊断通信协议栈中是CAN接口层。CAN接口层抽象了CAN控制器的位置和ECU的硬件布局,提供了一种平等访问总线通道的机制而无需考虑这些控制器的物理位置。服务层用于给应用程序提供可用的服务,在诊断通信协议栈里通过3个层次实现∶CAN传输层、Pdu路由层和 DCM 层。CAN 传输层主要解决多帧传输的问题,完成数据的打包和重组。Pdu 路由层是考虑到车载网络中有多种通信方式共存,实现不同通信数据的中转,可以对上层屏蔽通信方式的细节。DCM是服务层,也是整个诊断通信协议栈的核心。DCM 处理诊断仪发送来的服务请求消息,然后执行相应的操作,最后返回响应消息给诊断仪,整个过程涉及诊断会话的管理、诊断服务的调度及诊断服务的执行。本文采用 freescale 高性能芯片 MC9S12XEQ512 的开发板作为诊断通信协议栈开发和测试的硬件平台,该芯片内部集成5个支持 CAN 20B 标准的 CAN控制器,与之配套的 CAN 收发器采用 82C250 芯片。本文开发的诊断通信协议栈,选择实现UDS诊断服务, OBD服务会在以后进行扩展。整个协议栈的开发采用由下往上的方式,DCM以下的模块作为基本CAN通信软件一起开发,DCM作为诊断应用层单独开发。首先制定代码文件结构,然后分别进行基本CAN通信软件的数据传输、通信模式控制和时间管理功能的开发,最后进行 DCM层诊断服务处理功能的开发。AUTOSAR 的模块化思想很大程度上体现在代码文件结构的规范上。在AUTOSAR 标准里,诊断通信是作为一个完整的汽车电控系统的子系统进行开发的。诊断通信协议栈中的子模块不仅会调用各自的头文件,也会调用 ECU 级别的头文件,所以在保证代码的系统性的同时,也导致代码结构较为庞大复杂。本文旨在单独实现诊断通信的功能,因此对代码结构做了一定的简化,整个诊断通信协议栈的代码文件结构如图2所示。其中,Can_GeneralTypesh定义了通用 CAN协议栈底层模块的数据类型。ComStack_Typesh定义了与在线通信模块 Com 相关的数据类型,主要是数据协议单元。Std_Typesh定义了 Autosar标准专有的数据类型,如版本信息和一些状态模式的宏定义。每个子模块都有若干c 文件,主要定义仅限于本模块使用的数据类型、常量和函数。每个用子模块名称命名的头文件xxxh定义本模块中被外部引用的数据类型、变量和服务。xxx_Cfgh 定义了模块在预编译阶段用于配置的数据。xxx_Cbkh 和用 2 个模块名称命名的xxx1_xxx2h 声明了某模块被低层模块调用的回调函数。xxx_Typesh 定义模块专用数据类型。数据传输功能是基本通信软件的核心功能。本文为所有模块开发了数据传输接口,用于数据的收发、处理和格式转换。整个诊断通信协议栈的数据传输过程如下; 当总线上有数据发送过来时,首先经过 CAN 控制器硬件过滤,即进行标识只符的匹配过滤。如果通过过滤,CAN驱动将通过中断或轮询间的方式触发 read () 操作取出 CAN 控制器硬件接收缓冲区的数据,然后调用 Canlf RxIndication ()将数据传递至 CAN接口层,CAN 接口通过查询标识符列表对数据进行软件过滤后,再调用上层的 xxx _Rxlndication ()进一步处理和传递数据,最后通过 Dcm __RxIndication ()将数据传递到 DCM层。当发送数据时,高层模块通过依次调用低层模块的 xxx _Transmit()将数据往底层传递,最后通过 Can_Write()将数据写入 CAN控制器的发送缓冲区,数据再根据传送缓冲优先级依次发送到总线上,低层模块成功发送数据后通过返回 xxx TxConfirmation()告知上层模块。在 AUTOSAR 标准中,CAN通信协议栈的硬件可以包含多个 CAN控制器,但统一由同一个CAN驱动管理。CAN驱动是协议栈里面唯一可以直接访问和操作硬件的模块,它通过分配给每个CAN 控制器的 ID 获得对它们的访问。本文只采用了一个 CAN控制器,用于实现ECU 和诊断系统在单一网络中的通信。CAN驱动和上层模块的信息交互都要经过 CAN 接口层来传递。CAN 接口 层和驱动层之间的数据传输遵照 ISO11898-1 协议,对应于 OSI模型中的数据链路层,主要解决数据帧格式,实现标准帧和扩展帧的收发,数据单元格式为 L-PDU。单帧传输时,CAN接口层直接和 PduR 层进行信息交互。AUTOSAR 为 PduR 与其他模块之间的数据交换定义了一个交互层,PduR 通过查询 I-PDU 标识符列表对数据进行路由选择,数据格式为I-PDU。多帧传输时,CAN接口层和 PduR 层之间需要 CAN传输层来进行数据的打包和拆包。CAN传输层和 PduR 层之间仍遵照交互层。CAN 接口层和 CAN传输层之间的数据传输遵照 ISO15765-2,对应于OSI模型中的网络层,主要完成寻址和多帧传输的控制,数据格式为 N-PDU。图3以开发过程中的多帧传输为例,展示了各数据单元的格式和映射关系。
当工作条件发生改变时,如 ECU 上电和断电,各模块的状态或模式会自动进行转换。当通信需求改变时,需要主动切换模式,为此本文开发了—系列接口函数,主要用于切换通信波特率、CAN控制器状态、PDU通道模式。UDS的一些诊断服务如 link control要求可以切换通信波特率,以满足与不同诊断仪的通信。在 CAN 驱动层开发了 Can_SetBaudrate()设置波特率,入口参数是目标波特率的ID,波特率ID的选用参照 ISO14229-1。CAN控制器有4种状态∶ UNINIT,此时 CAN控制器未初化;STOPPED,此时 CAN控制器初始化,但不参与总线; STARTED,此时CAN控制器可以正常工作;SLEEP,此时 CAN控制器休眠以降低能耗,但可以被事件唤醒。CAN控制器状态在不同的通信条件下进行切换,统一由 CAN 接口层管理,经由驱动层实现。本文为此分别开发2个函数,接口层的 Canlf SetControllerMode()和驱动层 Can_ SetControllerMode()。软件通过 Canif SetController- Mode()发出状态切换请求,然后调用Can SetControll- erMode()操作 CAN 控制器的模式控制寄存器,CAN驱动层的控制器状态可以立即切换,CAN 接口层的控制器状态需等到驱动层返回E_OK后才切换。
为了可以根据需求改变通信信道的收发模式,本文在CAN接口层开发了功能函数 Canlf_SetPduMode ()用于实现L-PDU 信道4个状态的切换∶ CANIF OFFLINE,此时不进行通信; CANIF PASSIVE,此时只接收不发送数据; CANIF_ACTIVE,此时只发送不接收数据;CANIF_ON- LINE,此时进行正常的数据收发。状态机如图4所示。
此外,在CAN传输层还通过CanTp_Shutdown()实现CanTp_ On 到 CanTp_Off 的状态切换,从而关闭多帧数据传输功能。
2.4 时间管理功能的开发
在 CAN接口层与 CAN传输层进行多帧传输时,为了防止因总线负载过高或等待时间过长导致诊断通信失去联系,本文遵照 ISO156765-2 中对网络层定时的规定,开发了 CAN传输层函数 CanTp_MainFunciton()对通信的时间参数进行控制,主要参数有 N As、N_Bs、NAr、N_Br、 N_Cr和 STM-min。
其中,STM-min决定连续帧的发送间隔,由接收方通过流控帧发给发送方,其他的时间参数都有各自的定时器,如果发生超时,定时器溢出,报告错误。假设与 ECU 进行诊断通信的诊断仪的内部协议栈也是基于 AUTOSAR 架构进行开发的。
2.5 诊断服务处理功能的开发
UDS诊断服务总共分为六大类∶ Diagnostic and com- munication management、Data transmission、Stored data transmission、InputOutput control、Remote acti- vation of routine、Upload and download。ISO14229—1对每个诊断服务作了详细的规定,包括服务请求消息的服务标识符、子功能和数据参数,服务响应消息的服务标识符和否定响应码。
DCM 模块对一个诊断服务的处理,首先需要及时对服务请求消息进行接收,其次需要对服务请求消息进行验证,最后执行有效诊断服务请求的操作。本文对应以上要求,为 DCM模块分别开发了3个子模块∶ DSL、DSD、DSP。
DSL 直接与 PduR 进行数据交换,完成服务请求消息的接收和服务响应消息的发送。当接收到 DiagnosticSession-Control(10 hex) 服务时,DSL 根据请求切换诊断会话模式,并返回诊断会话的定时参数,如发送服务请求消息的一方收到服务响应消息的时间间隔 P2CAN Client,用于设定当前会话模式下应用层的超时机制。当接收到 SecurityAc- cess (27 hex) 服务时,DSL返回种子,然后再收到对方发来的密钥并验证,决定是否开放安全权限。诊断仪为了保持连接,会周期性生地发来TesterPresent 服务,DSL 接收后将复位 session timeout timer 以维持当前会话模式,此后不再将该服务发给 DSD 做进一步处理。
DSD 模块首先负责验证服务请求消息的有效性。包括检查服务标识符是否在支持的服务列表里,检查当前会话模式、安全权限和ECU状态是否支持该服务,检查服务子功能和参数格式是否正确。如果发现消息无效,则返回对应的否定响应码。如果请求消息通过有效性验证,DSD将通过诊断服务列表索引到 DSP 模块对该诊断请求的执行函数。
DSP 模块负责执行服务请求的操作,此时需要 DSP 模块和诊断通信软件之外的模块进行交互。当服务请求消息请求的是读取或清除故障信息,DSP 需要访问 DEM模块; 当请求数据上传下载或读取数据流时,DSP需要访问memory stack。当请求输入输出控制时,DSP需要通过 DCM_Send/ ReceiveSignal ()接入RTE来获得对 SW组件的访问。
3. 诊断通信协议栈的测试
3.1 故障诊断测试平台
本文借助于自主搭建的故障诊断测试平台对开发的诊断通信协议栈进行功能和协议的验证。诊断设备采用自主开发的PC式故障诊断系统,该系统运行在个人电脑上,然后通过自主开发的 VCl(车辆通信接口)接入车载诊断网络中,从而和挂载在同一网络中的ECU进行诊断通信,此时开发的诊断通信协议栈已经烧入 ECU中。测试平台如图5所示。
3.2 ECU刷新测试
本文参考 ISO15765-3 提供的非易失性内存再编程消息流程的例子,制订丁了一套ECU 刷新过程测试方案,用于测试协议栈的基本通信和诊断服务处理功能。在诊断通信网络中,诊断仪称作客户端,ECU称作服务器。采用标准的 11 位 OBD CAN id,参考ISO15765-4,配置客户端的物理请求 CAN ID为770,服务器的物理响应 CAN ID为 778,请求消息的 CAN 帧的无效数据填充 55hex,响应消息的填充 AA hex(如图6所示)。
采用 PC 故障诊断系统的数据监听功能进行测试。在进行诊断通信之前,PC故障诊断系统首先要对VCL进行配置,包括设定通信波特率为500kb/s,通过复位完成配置。
整个 ECU 刷新测试流程如下; 诊断会话控制- 切换到编程会话模式(0x10 02);安全访问 -获得种子(0x27 01)、发送密钥(Ox27 02);例程控制 -清除内存 (Ox31 01FF 00);请求下载 (0x34);传输数据(0x36);请求退出传输(Ox37);例程控制一检查编程依赖性 (Ox31 01 FF 01);E-CU复位-硬件复位(Ox11 01)。考虑本文测试采用手动方式发送服务请求,难以做到周期性发送诊断仪在线服务,为此屏蔽了 ECU 的断仪在线请青求超时错误功能。依次发送以上诊断服务,每发送一个诊断r请青求消息,立即收到ECUJ返向来的响应消息,每条消息有 8个数据字节,首字节为有效数据个数,然后分别为响应服务标只符、子功能和数据参数。
通过以上测试表明,开发的诊断通信协议栈具有基本的通信功能并且可以正确响应诊断请求,整个过程符合协议要求。