XCP学习
作者:mmseoamin日期:2024-01-22
  • XCP介绍

    XCP是一种通用的测量和标定协议,C代表Calibration,P代表Protocol,X代表总线类型,可以是CAN、ETHERNET、USB等等,最常用的就是XCP on CAN。通过XCP可以在系统运行时进行参数修改和信号测量,从而最优化ECU的参数配置,避免了以前传统的“修改代码-编译-烧写-测试”方式,提高效率的同时也减少了出错几率。

    XCP是一种主从式通信,上位机工具作为Master,目标ECU则是Slave,所有功能都是通过主从之间的通信交互实现。

    XCP学习,第1张

    从上图能够看到,主从之间的交互信息可以分为两类,一类是命令报文CTO(Command Transfer Objects),由Master发送命令(CMD),Slave进行应答(RES/ERR/EV/SERV);一类是数据报文DTO(Data Transfer Objects),包括数据采集(DAQ)及激励(STIM)。

    • XCP报文定义

      XCP报文由三部分组成:Header、Packet和Tail,其中Header及Tail由使用的传输层协议决定,比如对于CAN总线来讲,Header为空,Tail则为填充部分。XCP Packet分为标识域(Identification Field)、时间戳域(Timestamp Field)和数据域(Data Field),见下图所示:

      XCP学习,第2张

      标识域(Identification Field)

      标识域由PID、FILL和DAQ组成,PID(Packet Identifier)顾名思义标识了整个Packet的作用,对CTO来讲就是命令码/应答码,CMD报文取值0xC0~0xFF(例如PID=0xFF时表示CONNECT命令),SERV、EV、ERR和RES取值0xFC~0xFF,对DTO来讲就是ODT编号,DAQ报文取值0x00~0xFB,STIM报文取值0x00~0xBF;FILL和DAQ只在DTO下才有,FILL用于特定情况下的字节对齐填充,DAQ则表示列表编号;关于ODT和DAQ后面还会提到。

      时间戳域(Timestamp Field)

      CTO没有时间戳,DTO有但也是可选的,时间戳只在每次DAQ读取的首个ODT中存在。

      数据域(Data Field)

      在CTO中存放命令参数或者应答信息,在DTO中存放数据信息。

      • CTO

        XCP的命令分为两类,一类是协议固定要求的,必须实现/支持,一类则是可选的,可以不用实现/支持,比如下表是XCP部分的命令说明:

        Command

        PID

        Optional

        CONNECT

        0xFF

        No

        DISCONNECT

        0xFE

        No

        GET_STATUS

        0xFD

        No

        SYNCH

        0xFC

        No

        GET_COMM_MODE_INFO

        0xFB

        Yes

        GET_ID

        0xFA

        Yes

        SET_REQUEST

        0xF9

        Yes

        GET_SEED

        0xF8

        Yes

        UNLOCK

        0xF7

        Yes

        SET_MTA

        0xF6

        Yes

        UPLOAD

        0xF5

        Yes

        SHORT_UPLOAD

        0xF4

        Yes

        BUILD_CHECKSUM

        0xF3

        Yes

        TRANSPORT_LAYER_CMD

        0xF2

        Yes

        USER_CMD

        0xF1

        Yes

        像CONNECT、DISCONNECT、GET_STATUS、SYNCH都是必须要支持的,其它诸如GET_ID、SET_REQUEST、GET_SEED则是可选的,限于篇幅,本文不会讨论所有的命令及其参数细节,相关信息可以参考XCP的传输层协议规范。

        XCP支持主从之间三种不同的命令/应答交互方式:标准通信、块传输和交叉通信。

        标准通信(Standard)

        标准通信即是经典的一问一答方式,Master发送请求,Slave发送应答,并且在Slave响应前一个请求前,Master不能发送下一个请求。

        XCP学习,第3张

        块传输(Block)

        块传输类似多问一答或者一问多答,指在有大量数据交互的情况下(如上载、下载及flash编程)能够缩短传输时间,提高效率。

        XCP学习,第4张

        交叉通信(Interleaved)

        交叉通信类似多问多答,Master发送请求时不需要等到前一个请求被Slave应答。

        XCP学习,第5张

        • DTO

          ODT&DAQ

          通常目标观测量都是内存中的变量Element,每个Element都有自己的地址和长度,根据这些地址和长度信息可以将多个Element拼在一起成为ODT(Object Description Table)条目,相应的这些Element就称为ODT_ENTRY,然后将多个ODT条目排列在一起成为DAQ(Data AcQuisition),多个DAQ组成DAQ list,最终,ODT_ENTRY、ODT和DAQ构成了一个三维空间(见下图),当然这空间并不是无限延申的,各个维度都有自身限制。

          XCP学习,第6张

          DAQ既可以静态配置也可以动态配置,动态配置需要使用FREE_DAQ、ALLOC_DAQ、ALLOC_ODT和ALLOC_ODT_ENTRY四个命令。

          XCP学习,第7张

          动态分配遵循从大到小的原则,首先释放DAQ,接着分配DAQ,然后分配DAQ下的ODT,再来是ODT下的ODT_ENTRY,分配完了之后,ODT_ENTRY内容还是空的,还需要将其和内存中的Element进行赋值绑定。

          XCP学习,第8张

          测量模式

          上面说的DAQ有什么用呢,在说明之前,先来看下如果想通过XCP观测一个变量,最简单的方式大概就像下图所示采用查询方法了:

          XCP学习,第9张

          这里为了获取观测量的最新状态,Master需要周期不断的发送请求命令,Slave则通过响应命令将值发回给Master,采用这种方式首先效率不高,如果同时观测多个不同量的话数据一致性也无法保证,timestamp机制也没法使用。

          如果使用DAQ的话,在启动测量后Slave根据内部DAQ的trigger event发送观测量,不再需要Master去主动请求,并且可以实现不同级别的数据一致性,比如实现ODT级别的数据一致性,一个ODT内的所有ODT_ENTRY会在同一时间进行采样:

          XCP学习,第10张

          也可以实现DAQ级别的数据一致性,DAQ内的所有ODT会在同一时间进行采样:

          XCP学习,第11张

          XCP还提供了一种低性能的测量方式,该模式只会用来观测ECU内部那些对资源消耗不大的数据:

          XCP学习,第12张

          事件通道(EVENT CHANNELS)

          每个事件通道对应一个周期时间,决定了该通道下数据传输的频率,一个通道下可以有多个DAQ:

          XCP学习,第13张

          • 在线标定

            标定量一般都是放在Flash内的,而Flash中的数据在运行时是无法修改的,那要如何去进行在线动态标定呢,实际上XCP会将Flash中的标定数据映射到RAM中,在程序运行时使用的是RAM中的数据,这样在线标定改的是RAM里的内容,从而可以动态体现变量修改前后的行为变化。

            XCP学习,第14张

            XCP甚至可以将一份标定数据映射为多份,每份可以进行不同的参数配置,从而方便在不同标定配置间灵活切换。