在本系列文章将介绍 CAN 标定协议 (CCP) 和基于CAN的通用的观测和标定协议 (XCP) 的基础知识,具体内容将包括介绍 CCP/XCP 帧结构、实际通讯数据和 A2L 文件,通过轮询/DAQ 进行实际 ECU 数据记录的方法以及如何解码数据等内容。本文将先介绍其中部分内容,目录如下:
3)CCP/XCP的使用场景
4)XCP 与 CCP 的主要变化
2 CCP 报文类型
1)CRO,命令接收对象
2)DTO,数据传输对象
#1 CRM-DTO:命令响应报文
#2 EV-DTO:事件报文
#3 DAQ-DTO:数据采集报文
3 如何通过CCP记录ECU数据
1)通过 CCP 轮询获取数据
2)通过 CCP DAQ 采集数据
#1 如何配置 DAQ 序列
#2 如何初始化 DAQ 序列
#3 如何断开与 ECU 的连接
4 小结
1 什么是 CCP/XCP?
CCP是一种接口,可实现对电子控制单元 (ECU) 的读/写访问,可实现标定、数据测量、刷新等功能;XCP可理解为是CCP 的扩展与升级,具有多项改进,包括支持更多传输层,例如以太网和FlexRay等。所以CCP/XCP 协议有很多重叠之处,但也有重要区别。为了避免混淆,这里先重点介绍 CCP 协议,然后介绍基于CAN的 XCP,并明确说明它俩的重要区别点。
我们知道CAN总线使汽车中不同 ECU 之间的数据通信成为可能,每个 ECU 的输入和输出都将在 CAN 总线上传输。然而ECU 的内部工作对我们来说是一个黑盒,或者说ECU软件具体的运行情况我们无法知道,因为我们只能获取CAN信号。如果我们想要或者更多ECU的内部工作/运行情况,那么可以通过CCP/XCP协议来获取,即CCP/XCP可以直接访问 ECU 的内部工作情况,通过请求高频参数数据形式,此外CCP/XCP还允许修改 ECU算法和变量,从而更容易测试和标定ECU。更重要的是,CCP/XCP 以标准化的方式在 ECU供应商之间使用这些接口。
1)CCP/XCP历史
CCP最初由一家标定系统公司 Helmut Kleinknecht 开发。几年内,它由一个工作组 ASAP(应用系统标准化协会)进行了改进,该工作组的成员包括奥迪、宝马、大众等。后来 ASAP 更名为ASAM (自动化和测量系统标准化协会),其具体历史是:1992 年:Helmut Kleinknecht 首次发布 CCP 1.0
1995 年:ASAP 制定了 CCP 1.01 标准化
1996 年:ASAP 发布 CCP 2.0
1998 年:制定 CCP 2.01 和 CCP 2.1 草案
1999 年:CCP 2.1 于 2 月发布
2003 年:XCP 1.0,包括对 CAN、以太网、SPI、USB 的支持
2008 年:XCP 1.1 包括对 FlexRay 的支持
2013 年:XCP 1.2,包括 ECU 描述文件更新 + CAN FD
2015 年:XCP 1.3 包括 ECU 状态、旁路处理、时间相关性
2017:XCP 1.4 包括改进和新的 DAQ 模式
- 2017:XCP 1.5 包括无需调试适配器的软件调试
实际上许多 ECU 仍在使用 CCP,因此了解这两种协议及其主要区别至关重要。CCP/XCP 协议基于单主/多从概念。外部测量和标定工具(例如 CANape/INCA)充当主设备,并能够从一个或多个 ECU(又称从设备)读取/写入。主设备和从设备之间的接口称为 ASAP1 或 ASAM MCD-1。CCP/XCP 协议还描述了主设备和 ECU 描述文件之间的 ASAP2 或 ASAM MCD-2 MC 接口。实际上,该数据库以标准化文件格式(称为 A2L(ECU 描述文件))描述有关 ECU 的所有相关信息,下面会具体介绍。
3)CCP/XCP的使用场景
CCP/XCP协议主要用于OEM开发阶段,其支持:4)XCP 与 CCP 的主要变化
2 CCP 报文类型
为了了解 CCP 通信的工作原理,我们先看 CCP 报文类型。CCP通信是通过请求/响应机制来完成,与UDS 类似,这种通信由两种类型的报文组成:命令接收对象 (CRO)和数据传输对象 (DTO)。1)CRO,命令接收对象
命令接收对象 (CRO) 是主机向从机ECU发送的CAN 帧。数据有效载荷的第1个字节是命令字节 (CMD),CMD控制主机向 ECU 发出什么命令。为了跟踪发出的命令,第二个字节是一个计数器 (CTR)。主机发送的每个命令都会累加 1,并在从机ECU的响应中镜像,其余 6 个字节取决于命令。有关 CCP 中使用的 CRO 命令列表,请参见下表。关于CCP CAN帧ID,在 CCP 中使用两个CAN ID:一个用于主机发送报文( 0x701),另一个用于从机发送报文(0x702)。这两个ID将作为 A2L(又称 ECU 描述文件)的一部分,这意味着主机将在启动连接之前获取此信息。
通常,CCP 使用低优先级 ID,以避免干扰总线上的安全关键信息,这意味着主机不是通过各种 CAN ID 来定位特定的 ECU,而是通过如下所示的连接序列来定位,用于初始化与特定 ECU 通信的 CRO 示例:此处CAN ID 反映 CCP 主机用于通信的 ID。第 1 个字节为 0x01,对应于 CONNECT 命令,如上面的CMD表所示;第 2 个字节是 CTR 值;第 3 和第 4 个字节特定于 CONNECT 命令,对应于目标 ECU 的站地址(按 intel字节顺序),换句话说,主机使用上述 CRO 与 ECU 0x0139 建立连接。在这种情况下,所有后续通信都将与此特定ECU进行,直到主机终止连接或连接到另一个 ECU。2)DTO,数据传输对象
数据传输对象 (DTO) 是 ECU 向主机发送的 CAN 帧。DTO 有三种类型,如下所述:#1 CRM-DTO:命令响应报文
CRM-DTO 由 ECU 发送,用于响应来自主机的 CRO。此处的 CAN ID 反映 ECU 使用的 CAN ID(例如 0x702)。- 第一个字节是数据包标识符 (PID)。对于 CRM-DTO,PID 始终等于 0xFF。
- 第二个字节是错误代码(ERR),可用于例如通知主机请求无效。
- 第三个字节是计数器(CTR),它将与主机的 CRO 中的 CTR 值匹配。
- 剩余 5 个字节的结构取决于 CRO 中提出的原始请求。
下面是先前的连接示例trace,其中包括积极响应的 CRM。此数据显示与站地址为 0x0139 的 ECU 的连接,该 ECU 响应主机发送的初始化命令。显然,第一个字节是 0xFF(因为该报文是 CRM)。第二个字节显示没有发生错误,而第三个字节与 CRO 的 CTR 匹配。通过此序列,建立了主机与 ECU 0x0139 之间的连接。下表中我们展示了一组 CRM-DTO/EV-DTO 错误代码值。请注意,错误代码可以在 CRM-DTO(如果它们发生在对主机的 CRO 的直接响应中)或 EV-DTO(如果它们与主机的 CRO 命令异步发生)中发送。#2 EV-DTO:事件报文
EV-DTO 由 ECU 发送,用于响应导致 ECU 状态发生变化的内部事件。这可用于通知主机自上次 CRO 以来发生的错误。EV-DTO 的结构与之前的 CRM-DTO 相同,EV PID 始终等于 0xFE。请注意,CTR 与 EV-DTO 无关。#3 DAQ-DTO:数据采集报文
ECU 使用 DAQ-DTO 来响应特定事件(例如循环计数器、按钮或类似事件)自动将数据发送到主机。在 DAQ 通信中,主机首先会“配置”ECU 以进行特定的测量序列。一旦启动,ECU 将输出 DAQ-DTO,而无需主机进一步发送 CRO。在 DAQ-DTO 中,PID 是对“对象描述符表”(ODT)的引用,而最多 7 个字节携带与 ODT 相关的数据。稍后将对此进行详细介绍。下面是 ECU 向主机发送 DAQ-DTO 报文的示例。该数据显示了遵循初始配置序列的从属设备的 DAQ-DTO 通信。数据与 ODT 列表 #37 (0x25) 相关,有效载荷为 5 个字节。请注意,我们没有填充未使用的字节(因为 DAQ-DTO 不需要这样做),另外,如何为此 DAQ 响应引入新 CAN ID(稍后会详细介绍)。CRO、CRM-DTO 和 EV-DTO 报文的有效负载长度必须为 8。任何未使用的字节都用任意值填充(在本介绍中使用 0xAA)。DAQ-DTO 报文可以使用实际的有效负载大小。3 如何通过CCP记录ECU数据
通过CCP记录ECU数据有两种方法:轮询(Polling)和 DAQ。1)通过 CCP 轮询获取数据
下面我们来说明一下这种获取ECU数据的流程,如下所示:
这里主机向从机发送请求,请求存储在“源地址”0x12345678 的 0x04 字节数据。第 4 个字节是 0x00,它反映了此 ECU 源地址的“地址扩展”,它也可以反映特定的内存段。对于这个特定的源地址,从机用 4 个字节的数据 0xF12A712F 进行响应。上述流程可用于提取实时参数数据,比如发动机转速,发动机扭矩等关键信号。实际上,“轮询”只是主机使用名为SHORT_UP的命令的一系列 CRO/CRM-DTO。轮询设置起来很简单,只需建立 ECU 连接并每隔多少毫秒发送正确的请求消息即可。就许多实际用例来说,这可能是一个完全可行的解决方案,但轮询有两个明显的缺点:一个是轮询效率低下。轮询要求每次响应都发送一个请求消息。如果需要测量100Hz的2字节信号,则总线负载将增加200帧/秒。效率低下既是由于需要请求每个单独的响应,也是因为响应消息被强制为 8 个字节长,其中 3 个字节用于开销。
另一个是轮询是异步的。轮询多个信号时,需要按顺序发送请求/响应,每个请求之间留有较小的延迟。也就是说信号观测不是同步的,这将使数据分析和后期处理精度较低。
2)通过 CCP DAQ 采集数据
CCP 提供了一种称为 DAQ(同步数据采集)的替代数据测量技术,DAQ 的启动稍微复杂一些,但解决了轮询的两个缺点。DAQ 的工作原理是:主机指定要从机记录哪些测量值,以及哪些事件应触发数据通信。比如主机可以要求每 10 毫秒广播一次信号A和B,而每 100 毫秒广播一次信号C等。一旦 DAQ配置完成,主机就会“启动”序列,从机使用DAQ-DTO报文自主广播请求的信号,无需主机发送请求报文。与CRM-DTO相比,DAQ-DTO中的信号数据打包效率更高,占用总线的负载更低,另外使用DAQ可以将相关信号打包在相同的DAQ-DTO帧中,确保以时间同步的方式测量所请求的信号,即可提高分析数据的质量。#1 如何配置DAQ序列
为了使用DAQ模式进行数据测量,主机需要先对ECU进行相应的配置,这个过程通常由复杂的 GUI 工具处理,这里暂不做介绍。DAQ 中有两个关键概念:对象描述表 (ODT)和DAQ 列表。- 对象描述表(ODT)
对象描述表 (ODT) 是来自 ECU 内存的数据元素的引用列表。如果我们以 CCP 轮询中使用的“SHORT_UP”为例,主机发送一个请求,其中指定三个元素:数据长度(以字节为单位)、地址扩展和源地址。通过这些信息,ECU可以找到数据并将其发送给主机。ODT 的概念类似:ODT只是元素引用的列表,ODT中的每个条目都反映了ECU源地址,并且还可能反映了地址扩展和数据长度,即ODT条目包含了与用于轮询信号的相同信息。比如要记录7个信号,每个信号的长度为1字节,这样可以定义一个包含7个元素条目的新ODT#0(PID 0x00)。元素1指的是具有特定ECU源地址的信号1,元素2指的是具有另一个源地址的信号2,以此类推。当使用DAQ模式进行数据测量时,可以参考 ODT#0,以便让ECU在单个DAQ-DTO CAN帧内提供所有7个信号的时间同步数据。换句话说,我们定义的ODT描述了DAQ-DTO报文的结构,这意味着ECU现在知道如何将7个信号字节打包在单个 CAN 帧中,并且主机知道如何从该 CAN 帧中提取 7 个信号字节。注意:如果我们要轮询所有7个信号,则每个周期将需要14个CRO/CRM-DTO CAN 帧,现在不仅只需要1个DAQ-DTO CAN帧,而且将这7个信号绘制在一起,因为它们共享相同的CAN帧时间戳,这使得分析变得更加容易。实际上,主机通常会定义多个 ODT列表,并为每个列表分配0x00至0xFD范围内的PID,然后每个 ODT 定义单独的DAQ-DTO结构。- DAQ 列表
使用多个ODT列表时,将它们分组很有用,这些 ODT 列表组称为 DAQ 列表,如下图所示,DAQ 列表 #0 可能包含 ODT #0、ODT #1 和 ODT #2。换句话说,对于数据测量请求的每个唯一采样逻辑都需要一个单独的 DAQ 列表。接下来我们来了解下DAQ 和 ODT 初始化,先看下已经启动的 DAQ 序列数据:从第一个字节从 0x00 到 0x02 可以看出,目标 ECU 总共在三个ODT列表中广播数据,这三个 ODT 被分成两个 DAQ 列表。一个 DAQ 列表包含采样频率为 10 毫秒的 ODT #0,另一个DAQ 列表 #1 包含其余 ODT 列表 #1 至 #2,采样频率为 100 毫秒。这就是为什么与其他 DAQ-DTO 相比,PID 为 0x00 的 DAQ-DTO 出现的频率更高的原因。#2 如何初始化 DAQ 序列
DAQ 列表的配置是通过 CRO/CRM-DTO 帧序列(可能很长)完成的。在这里,主机基本上逐个元素指定整个 DAQ/ODT/元素结构。要定义新信号(又称元素),主机指定地址、长度和地址扩展。接下来,主机通知 ECU 如何通过将元素链接到 ODT# 和 DAQ# 来将元素打包到 DAQ-DTO 中。为了详细了解这一点,看一下如下数据:首先使用 CRO 命令 GET_DAQ_SIZE。目的有两个,一是告诉我们指定 DAQ 列表在 ODT 列表方面的大小,二是清除当前列表。本质上这就像 DAQ 列表的“重置”命令。作为 GET_DAQ_SIZE 命令的一部分,我们还在最后 4 个字节中提供了 11 位 CAN ID 0x712。这是告诉ECU 它应该使用 CAN ID 0x712 来广播后续的 DAQ-DTO。这很微妙,但却是一个重要的方面:本质上,主机能够为每个 DAQ 列表指定 CAN ID,这反过来也使主机能够并行启动跨多个 ECU 的 DAQ 测量。ECU 确认来自主机的 CRO,并通知DAQ 列表 #5 有 3 个 ODT,第一个 PID 为 0x07。接下来,主机开始用 7 x 1 字节信号的源地址信息填充 DAQ 列表 #5 和 ODT 列表 #7。这是通过一个由 7 次重复两个命令组成的简单循环完成的:SET_DAQ_PTR 和 WRITE_DAQ,其具体过程是:- 首先,主机使用 SET_DAQ_PTR “选择” DAQ 列表 #5、ODT 列表 #7 和 ODT 列表的元素 #0。
- 接下来主机使用 WRITE_DAQ 写入此元素引用的内容:长度为 1、地址扩展为 0 和源地址为 0x00001000。
到此就告诉 ECU 将第一个信号的值(存储在指定的源地址中)“打包”到与 DAQ 列表#5 和 ODT 列表#7 相对应的 DAQ-DTO 的第 2 个字节中(DAQ-DTO 的第一个字节是 PID 0x07)。此后,对剩下的 6 个信号重复该过程,直到 ODT #7 完成。在这个简单的情况下,我们只关心这个特定的 DAQ 和 ODT 列表,因此最后一步是通过 START_STOP 命令启动 DAQ 测量。在这里指定启动 DAQ 列表 #5 和 ODT 列表 #7,那么ECU 现在将开始以指定的频率广播来自 DAQ 列表 #5 和 ODT 列表 #7 的数据,CAN 帧有效载荷包括第一个字节中的 ODT PID 0x05 和剩余有效载荷中的 7 个“元素”信号值。注意,我们也可以使用 START_STOP 命令来“准备”多个 DAQ 列表和 ODT 列表进行测量,然后使用 START_STOP_ALL 命令同时启动或停止所有列表。#3 如何断开与 ECU 的连接
一旦数据采集完成,主机可以通过 DISCONNECT 命令断开与 ECU 的连接,如下所示:这里第三个字节 0x01 表示完全结束会话(与暂时断开连接相反),实际上重置 ECU,这里也指定了 ECU 的站地址(Intel 格式)0x702。由此可以看出DAQ 的设置更加复杂,但能够实现 ECU 数据的有效时间同步通信。通过上述介绍,我们可以知道CCP/XCP的基本概念,也了解CCP报文类型和内容,以及通过 CCP 记录 ECU 数据。下篇文章继续了解如何解析这些数据和A2L文件解析。
汽车研发交流群,有兴趣的朋友请添加群主:prOmiseyes,备注:公司+职务入群。仅限汽车从业人员。