XCP协议与A2L协议详细分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、XCP协议和A2L文件–
A2L(ASAP2)解析
ASAP2标准是一个比较复杂的标准,详细的一条一条讲解标准内容并没有太大的价格,我们将主要以一种应用的方式来带领大家认识ASAP2标准理解作为ASAP2表现形式的A2L 文件的作用,最后学会如何阅读和修改A2L文件。
首先我们要搞清楚什么是A2L什么是ASAP2标准,简单来说ASAP2标准是ASAM组织制定的一套标准,该标准规定了上位机(Master)和ECU(Slave)之间的通讯所需要的所有信息(可以是XCPonCAN,XCPonUSB等,也可以是CCP,还可以是UDS),而A2L 文件就是ASAP2标准的表现形式,符合ASAP2标准的A2L文件主要含有两部分内容:ECU 的描述信息和通讯方式的描述信息。
什么是ASAP2标准
ASAP2标准是ASAM在1998年提出来的,现在它的名字叫做ASAM MCD-2MC/D,是ASAP标准中的第二部分。
整个ASAP有3部分内容,ASAP1描述了上位机(Master)和ECU(Slave)之间的通讯协议,我们这个系列文章介绍的XCP以及它的前身CCP都是属于ASAP1标准,ASAP2规定了Master端如何去描述和解析Slave端的信息,ASAP3规定了如何使用第三方工具和设备操作和控制上位机(Master),例如如何使用台架软件来控制标定测量工具去对ECU进行控制和测试。
ASAP2标准目前的版本为v1.6,对应的文件全名为:
ASAM_MCD-2MC_DataSpecifcation_V1.6.pdf
什么是A2L文件
前边介绍了,A2L文件是基于ASAP2标准书写完成的,那么A2L文件到底是什么东西了。
首先它是采用ASAP2指定的一套类XML语言的描述性语言(采用开标签和关标签来描述信息)书写的文件,它里边包含了某个特定的ECU中的软件和系统信息,还包含了上位机和ECU通讯方式的约定,它用来指导上位机和ECU的通讯交互过程,让他们对交互的信息有一致的认识,从而是上位机工具准确且友好的将ECU中的信息展现给用户。
下面我们来看一下A2L文件的结构和组成。
PROJECT
{
HEADER{...} /* Project description */
MODULE Device
{
MOD_PAR{...} /* Control unit management data */
MOD_COMMON {...} /* Module-wide (ECU specific) definitions */ CHARACTERISTIC{...} /* Adjustable objects */
CHARACTERISTIC{...}
...
AXIS_PTS{...} /* Axis points objects */
AXIS_PTS{...}
...
MEASUREMENT{...} /* Measurement objects */
MEASUREMENT{...}
...
COMPU_METHOD{...} /* Conversion method */
COMPU_METHOD{...}
...
COMPU_TAB{...} /* Conversion tables */
COMPU_TAB{...}
...
FUNCTION{...} /* Function allocations */
FUNCTION{...}
...
GROUP{...} /* Groups */
GROUP{...}
...
RECORD_LAYOUT{...} /* Record layouts of adjustable objects */ RECORD_LAYOUT{...}
}
} /* END OF PROJECT */
一个A2L文件只能有一个Project(项目),而项目中至少要有一个Module,A2L文件的注释和C语言的注释方式是一样的,支持/**/和//两种方式。
上边文件结构中,不同的文件块都有着重要的意义:
•HEADER:这个块里边包含了项目信息,包括项目编号,项目版本等信息。
•MODULE:这个块里边包含了在标定测量层面来描述ECU需要的所有信息,一个ECU对应一个MODULE块,MODULE由许多子块来组成。
o MOD_PAR:这个块里包含了用于管理ECU的数据,例如客户名,编号,CPU类型,ECU的内存分配等,其中最重要的就是ECU的内存分配,开发人员需要根据ECU内存分段情况定义MEMORY SEGMENT和SEGMENT里边的PAGE,这里的SEGMENT/PAGE的概念和在线标定中的概念是一致的,请参考在线标定篇章,一个MODULE里边只能出现一次;
o MOD_COMMON:这个块用来指定ECU的一些标准的一般性描述信息,比如大小端,数据的对齐方式,FLOAT变量的处理方式等,一个MODULE里边只能出现一次;
o CHARACTERISTIC:这个块用来定义标定变量,里边包含了可以被标定的变量的名字,地址,长度,计算公式,精度,最大最小值等信息,一个MODULE 里边可以出现很多次这样的块,也就是说一个ECU可以有很多的标定变量;
o AXIS_PTS:这个块用来定义数组或查表变量对应的轴的类型,它将被RECORD_LAYOUT块来引用,一个ECU里边可以有很多种不同的轴类型,用于实现查表和插值;
o MEASUREMENT:这个块用来定义测量变量,里边包含了可以被测量的变量的名字,地址,长度,计算公式,精度,最大最小值等信息,一个MODULE里边可以出现很多次这样的块,也就是说一个ECU可以有很多的测量变量;
o COMPU_METHOD:用于定义计算公式,及原始值和物理值之前的转换关系,这些公司可以被标定变量和测量变量来引用,从而将原始值转换成便于用户阅读和使用的物理值;
o COMPU_TAB:这个块用来定义原始值和物理值的映射关系,是一种特殊的转换关系,它一般应用于枚举变量,例如我们想采集一个代表XCP状态机的变量,分别为0对应DISCONNECTED,1对应CONNECTED,2对应RESUME,那么我们就可以把这样的映射关系定义层一个COMPU_TAB,然后关联到对应的变量上,这时候如果上位机采集到1这样的原始值,它就可以将当前的状态显示成
“CONNECTED”字样,方便用于阅读和使用;
o FUNCTION:这个块不是必须;
o GROUPS:这个块这个把标定变量和测量变量按照一定的逻辑(比如功能模块)组织起来,在上位机工具中形成一个下拉菜单,使得用于可以从中选择变量,这个块不是必须的;
o RECORD_LAYOUT:这个块用来定义标定变量的物理存储结构(单个变量,二维表,三维表等)。
上述的这些信息块可以分为两类,一类是随着ECU和XCP实施完成以后就确定的,这类信息一经确定以后再后续的使用过程中是不需要修改的,例如大小端,MEMORY SEGMENT内存分配等,上述HEADER/MOD_PAR/MOD_COMMON属于这一类,另外一类是当ECU软件有所调整的时候就会变化的,例如已有的标定变量和测量变量的地址,甚至变量名,或者可能会新增变量,上述
CHARACTERISTIC/AXIS_PTS/MEASUREMENT/COMPU_METHOD/COMPU_TAB/FU NCTION/GROUPS/RECORD_LAYOUT属于这一类。
在第二类中改动最多的尤其是
CHARACTERISTIC和MEASUREMENT快中的变量地址信息,因为每次软件变化重新编译都会造成这部分信息的更新,地址更新导致的块信息更新需要手动的更改A2L文件才能使得A2L和当前的软件配置起来,只有两者相匹配才能实现正确的标定和测量。
A2L块示例
1.测量变量vechicle_speed可以进行如下定义,该变量处于RAM中,对应的地址是
0xD0001234,它的范围是[0-230] ,它在ECU中以一个UWORD类型来表示,原始值和物理值的转换关系为:Phy = 0.003 X Raw ,即Ax+B中A=0.003,B=0v
/begin MEASUREMENT VEH_SPD
"Vehicle Speed."
UWORD
Vehicle_Speed_Conversion
0 0.000000
0.000000 230.000000
ECU_ADDRESS 0xD0001234
DISPLAY_IDENTIFIER vehicle_speed
/end MEASUREMENT
/begin COMPU_METHOD Vehicle_Speed_Conversion
"Ax + B"
RAT_FUNC
"%4.3"
"fact"
COEFFS 0.0 1.0 0.000000 0.0 0.0 0.003000000
/end COMPU_METHOD
2.测量变量xcp_state代表XCP的状态,可以进行如下定义,它处于RAM中,在ECU中的地址是0xD0005678,它是一个枚举量,0对应DISCONNECTED,1对应CONNECTED,2对应RESUME
/begin MEASUREMENT XCP_STATE
"XCP state"
UBYTE
XCP_STATE_ENUM
0 0.000000
0.000000 2.000000
ECU_ADDRESS 0xD0005678
DISPLAY_IDENTIFIER xcp_state
/end MEASUREMENT
/begin COMPU_METHOD XCP_STATE_ENUM
""
TAB_VERB
"%10.4"
""
COMPU_TAB_REF XCP_STATE_ENUM_TAB
/end COMPU_METHOD
/begin COMPU_VTAB XCP_STATE_ENUM_TAB
""
TAB_VERB
3
0 "DISCONNECTED"
1 "CONNECTED"
2 "RESUME"
/end COMPU_VTAB
3.标定变量Current_threshold可以进行如下定义,它处在FLASH标定区域,在ECU中的地址是0x00012345,它的范围是[-20,20],是一个有符号量,精度为0.125,即Phy = 0.125 X Raw
/begin CHARACTERISTIC Current_threshold
"Cur"
VALUE
0x00012345
Standard_SW
current_cmpu
-20.0 20.0
DISPLAY_IDENTIFIER Current_Vaule
/end CHARACTERISTIC
/begin RECORD_LAYOUT Standard_SW
FNC_VALUES 1 SWORD COLUMN_DIR DIRECT
/end RECORD_LAYOUT
/begin COMPU_METHOD current_cmpu
""
RAT_FUNC
"%6.2"
"A"
COEFFS 0.0 1.0 0.000000 0.0 0.0 0.125000000000 /end COMPU_METHOD
我们前边提到的,在每次软件有更新重新编译以后,会导致这些变量在ECU中的地址有变化,那么上边这些变量对应的ECU ADDRESS条目的内容就需要随着改变,变量的地址信息可以从编译生成的MAP文件中获得,然后手动更新到A2L中。
二、XCP协议和A2L文件– XCP 协议解析Part2
在上一篇文章中,我们解析了XCP协议中一些宏观的概念,在本篇文章中,我们将会利用CAN传输层来展示具体到XCP消息结构。
我们将首先从一个通用的角度来看XCP的消息结构,这里的通用指的是既针对CTO又针对DTO,然后我们会对基于CAN传输层的CTO 和DTO的消息结构分别进行讲解。
注:文章中所使用到的DTO概念适用于DAQ和STIM,但是举例和描述中都默认使用DAQ。
通用消息结构
通用的消息结构既适用于CTO也适用于DTO,通用的消息结构既适用于CAN传输层也适用于其他传输层,在构造不同命令的时候,通用结构里边的某些字段的含义不同或者是字段的长度不同。
一个完整的XCP消息(也可以说一帧XCP消息)由三部分组成,它们是XCP Header(XCP 消息头),XCP Packet(XCP消息体),XCP Tail(XCP消息尾),Header和Tail的存在是依赖于具体的传输层的,而Packet在不同的传输层上都是必须的。
Packet又有3个组成部分,分别是标识区(Identification Field),时间戳区(Timestamp Field),数据区(Data Field)。
对于CAN传输层来说,Header是不存在的,因此实际的XCP消息帧就是消息体加Tail,而Tail又于DLC的设置相关,如果DLC=8,但是消息体的长度又不够8个字节的时候,Tail的大小就是8减去消息体字节长度,Tail的内容就是CAN消息的填充(0xFF,0x00
或者其它指定的值),而如果DLC是根据消息长度设置的,那么Tail长度就始终是0。
1. 标识区:标识区用来标识该帧消息,用以和别的消息帧进行区分,告诉接收方现在这条消息是什
么类型,里边的数据代表什么意义。
从CTO的角度举例的话,它可以连接命令,可以是断开连接命令,也可以是标定页切换命令,这些命令在CAN消息层面来说,都是几个字节的数,那么接收方如何知道现在这条命令是什么命令呢,接收方就是通过标识区来识别的,不同的标识区对应不同作用的命令。
从DTO的角度举例来说,现在发送出来的ECU内部数据到底是哪部分的数据,对应于ECU中的哪个或哪几个变量,这些信息又是怎么同别的信息区分开来的呢,也是通过标识区。
2. 时间戳:时间戳用来反映本帧数据的时刻,它只有在DTO中是有效的,也就是说在CTO中时间
戳的长度是0即不存在。
跟标识区不同的是,标识区在DTO的每一帧中都存在,用以区别本帧
和其他帧的所代表的意义,而时间戳仅仅出现在一个DAQ中所有的DTO消息中的第一条。
这是因为DTO都是通过块传输模式通讯的,通过前边的文章,我们知道了ECU向上位机上传变量信息数据的时候通过DAQ,而DAQ反应在消息层面就是很多条DTO消息,对于同一个DAQ里边的DTO消息他们所代表的是同一时刻的不同数据,因此只要第一条消息中含有时间戳就可以代表整个DAQ消息块中所有消息的时刻。
如果大家对前边的概念有些遗忘,可以再去回顾一下DAQ 同步数据传输详解这篇文章。
3. 数据区:顾名思义,数据区包含了XCP消息的真正数据内容。
从CTO的角度来看,数据区里边
的数据代表着命令的参数,用来告诉接收方怎么去执行标识区标识的命令。
而从DTO的角度来看,数据区里边就是实际的ECU当中的变量的值或者内存里边的值。
CTO消息结构
CTO的消息包含了一个BYTE的标识区(PID),时间戳长度为0,剩下的都是数据区,因此消息结构就退化成了以下这样
针对不同的CTO命令,PID和DATA的数据格式都不同,具体的信息在XCP标准Part2中可以查到。
这里我们仅对PID部分做个简单的说明:
CMD:PID的范围是0xC0 — 0xFF,不同的PID代表不同的命令
RES:PID是0xFF,代表对于CMD的肯定响应
ERR:PID是0xFE,代表对于CMD的否定响应
EV:PID是0xFD,用于向上位机报告事件
SERV:PID是0xFC,用于请求上位机做某些动作
DTO消息结构
DTO的消息结构略微复杂一点,可以根据实际的ECU资源和应用情况选择使用不同的结构。
如下图所示,标识区和时间戳都有多种长度可以选择,不同标识区和时间戳格式是可以随便组合使用的。
1. 标识区:PID就是DAQ块通讯时候的DTO消息的编号,从0x00到0xFB,用来识别消息中数据
所代表的意义(类似于UDS连续帧中的消息计数),同时标识区可以最大扩充到4个Byte,后边可以放置目前数据所处的DAQ编号。
为什么要有这样的扩充呢。
利用CAN传输层举例来看,在XCP实施中,可以选取不同的CAN ID来标识不同的DAQ,这种情况下DAQ的标号对于接收方来说是可以通过CAN ID来区分出来的,另外一种方式是使用相同的CAN ID来处理不同的
DAQ,这个时候接受方就无法从CAN ID来区别不同的DAQ,那么就可以在标识区中增加DAQ 编号来达到这个目的。
2. 时间戳:根据实际的资源情况,时间戳可以从1、2、4字节的长度中来选择
PID的范围:
DAQ:PID的范围是0x00 — 0xFB
STIM:PID的范围是0x00 — 0xBF
PID范围总结
最后我们一目了然的看一下整个XCP通信中的PID取值分布情况:
三、XCP协议和A2L文件– XCP 协议解析Part 1
在接下来的两篇文章中,我们将主要通过XCPonCAN(即XCP运行在CAN传输层上)来仔细讲解XCP协议层的内容。
本篇文章主要侧重于XCP协议层中的通讯拓扑,通讯模型,状态机以及消息分类,下一篇文章主要侧重于XCP命令的格式。
通讯拓扑
XCP 通讯是一种点对点的通讯协议,即同一时刻单个Master和单个Slave之间进行通讯,通讯都是由Master来发起的,Slave根据实际情况来回答Master的请求,Slave端同一时刻只允许同一个Master建立连接。
但是,XCP协议也是可以支持网关的。
通讯模型
所谓的通讯模型指的是使用XCP通讯的Master和Slave之间的通讯方式,在XCP协议里边规定了支持三种通讯模型,标准型,块传输型(主块传输和从块传输两种),交替型。
标准型指的是一问一答的方式,块传输则是多问一答,交替型比较特殊,指的是,被问的一方可以根据自己的实际状态延迟做回答(多问多答)。
接下来大家看一下下边4幅图,大家可以在看图的同时思考一下,它们分别对应的是哪种通讯模型,然后看看自己都分析的是否正确。
上边4幅图从左到右对应的通讯模式分别是:标准型,主块传输型,从块传输型和交替型,你答对了吗?那么这4种通讯模型具体的使用场景是什么呢,为什么要分这4种模型呢。
1. 标准型。
同大部分CAN通讯协议一样,XCP首先支持一问一答的通讯方式,使用这种方式通讯
的时候,上位机向下位机发起某个请求,下位机根据上位机的这个请求执行相应的动作,并适当
的根据情况给予响应,上位机在收到下位机的响应以后才会发起下一个请求。
这种方式被应用到
大部分的XCP命令中。
2. 块传输型。
当一条CAN消息无法容纳一次通讯需要的全部数据的时候,为了减小交互时间,XCP
设计给出数据的一方不停的将全部数据发送出来以后,接收方才进行一次回复,典型的应用场景
为,XCP中的内存上传、下载、刷新命令。
在这种传输方式下,因为一方要不停的发送数据给接收方,为了保证数据能够正确不丢失的传输,XCP定义了两个参数,块传输过程中两帧的最小间隔时间MIN_ST以及一次快传输所能使用的最大的块大小MAX_BS。
3. 交替型。
这种传输方式比较特别,在实际应用中使用较少。
交替型传输意味着,收到数据的一方
(Slave端)在收到Master发来的请求以后可以不立即响应,这个时候Master可以继续发下一
条情况,从而在Slave端形成一个请求队列,Slave端可以根据自己的资源情况,当资源空闲时
再去一一服务和响应请求。
设计这种通讯模式的目的是考虑到有的ECU(Slave端)硬件资源有限,毕竟XCP是一种开发手段,在ECU软件设计中处于低优先级的服务,因此没办法及时响应Master发来的请求。
Slave状态机
Slave状态机是一个通讯协议中必不可少的一部分,它描述了使用通讯协议的时候,Slave 有哪些状态,状态间是的互相切换规则是怎么样的。
XCP在Slave端的状态机如下图所示。
XCP的状态机中只有简单的三个状态,DISCONNECTED,CONNECTED和RESUME状态。
当系统启动以后XCP会根据当前的RESUME模式是否使能来判断进入DISCONNECTED还是RESUME。
我们先来看一下大部分使用场景的RESUME模式关闭状态,RESUME模式我们稍后介绍。
当XCP处于DISCONNECTED状态下,除了连接命令以外的其他XCP命令都会被XCP协议栈忽略,只有当协议栈收到连接指令以后,协议栈才会切换到CONNECTED状态,在这个状态下,协议栈可以响应和处理所有的XCP命令(所有的标定猜数都是在这个状态下处理的)。
当处在CONNECTED状态下的协议栈收到断开连接的命令以后会退回到DISCONNECTED状态。
此外,当协议栈中发生了严重等级为S3的致命错误的时候,协议栈也会从CONNECTED状态退回到DISCONNECTED
状态。
这些严重度等级对应的具体错误在XCP的规范中可以查找的到。
我们刚提到系统启动以后会先检查RESUME模式是否使能,那么什么是RESUME模式呢。
从上边的状态图可以看出,如果要实现对系统的变量参数采集,上位机需要和XCP协议栈进行连接握手才能进行采集,其实在实际采集前的握手交互远不止这些,还有采集的变量列表的初始化(ODT/DAQ初始化),这些动作是非常耗时间的,而且需要上位机来发起,但是有时候我们需要实时的获取到ECU系统启动过程中的一些重要数据,那么在这种工作模式下,这些重要参数是没办法被采集到的。
为了解决这个问题,XCP引入了RESUME模式,在这种模式下,ECU在上次运行的时候,上位机可以通知它使能RESUME模式,并把需要采集的重要数据的ODT/DAQ描述存储到NVRAM中,然后ECU经过一次掉电和上电的复位以后,在启动过程中,协议栈会检查到RESUME模式已经被使能,那么就会直接进入RESUME状态来不停的将ECU中的指定参数发送出来。
值得注意的是RESUME模式跟DISCONNECTED模式有一个相同点就是,在这个模式下协议栈无法响应除了连接命令以外的其他命令。
一旦收到连接命令以后,协议栈会进入CONNECTED状态,同时停止数据发送,等待正常的命令交互。
消息分类
不同的命令各司其职从而实现了XCP的协议,对消息进行分类有助于更好的理解和实现XCP协议栈。
XCP的消息分为两大类:CTO(Command Transfer Object,命令传输对象)和DTO(Data Transfer Object,数据传输对象),顾名思义,CTO是指所有功能性命令的传输,DTO是指所有数据的传输。
CTO中又包含一种主发给从的CMD(命令),和四种从发给主的消息,RES(肯定响应),ERR(否定响应),EV(事件,在发生某些事件的时候,下位机用这种消息来通知上位机),
SERV(服务请求,在某些情况下,下位机虚需要请求上位机做一些动作,那么它将通过这种消息来发起请求)
DTO中包含了一种主发给从的STIM(反向DAQ),这种消息跟我们前边文章中介绍的STIM 和BYPASS功能使用相关,它用来大批量的向下位机发送数据。
另一种DTO是DAQ,这种消息用于大批量的将ECU中的数据发送给上位机,也就是数据采集和测量用到的主要消息。
四、XCP协议和A2L文件–在线标定详解
在前边的章节中我们也介绍过在线标定的基本用例,大家应该对在线标定实现的功能有了了解。
在这一篇文章中,我们将基于XCP标准中规定的在线标定的实现方式和一些概念,来讨论怎么在一个实际的ECU中设计在线标定方案。
首先大家来看一下下边的这个图,在XCP协议中,提出来PAGE(页)的概念,所谓的页就是对数据赋予了访问属性的概念,页是一种对数据的描述,一个SEGMENT中不同的页代表这相同地址上的相同的数据,唯一的区别是他们的数据内容和访问权限是不同的,下图
中SEGMENT1中的页1是ECU可以访问的,而页2只有XCP可以访问,这个图只是XCP 标准里边的示意图,在具体的在线标定实现中,没有这么复杂的页设置,一般来讲,在线标定只需要两个页,即Working Page(工作页)和Reference Page(参考页)。
在实际应用中,控制算法中正在使用或者访问的数据来源页被称为激活页(Active Page),页的切换动作会有XCP提供的命令来触发,同时XCP也会提供相应的命令可以获取现在ECU中的激活页编号。
同一个SEGMENT里边的不同的页通过PAGE_NUMBER这样的术语来索引,页的索引都是从0开始,连续递增的。
这个图中提到的SEGMENT表示的是ECU地址分配的逻辑分区(与FLASH物理状态无关,纯逻辑应用概念),举例来说SEGMENT1可以是标定区,SEGMENT0可以是程序区,每一个SEGEMENT可以有多个页。
SEGMENT
是用SEGMENT_NUMBER这样的术语来索引的,该索引页是从0开始连续递增的,而SECTOR则代表着ECU地址分配的物理分区,它就是指FLASH的物理分区状态,每一个SECTOR代表一个单独可擦除的物理分区。
那么,这些PAGE啊SEGMENT的概念是怎么和在线标定联系起来的。
首先,有个概念我们要明确一下,所谓标定数据,就是控制算法中使用的一些固定的参数,这些参数在完成开发阶段的调优以后就会固化起来,因此显而易见,这部分数据会被分配到ECU的FLASH
区域中,而作为ECU开发阶段重要过程的参数调优(标定过程)则要求这些数据可以通过通讯(XCP等)能够实时被修改,因此这部分数据又需要被分配到ECU的ram中。
而数据的承载形式-变量在编译链接以后只能有一个地址,因为标定数据本质上看是固定的参数,因此他们会实际被配置到FLASH中。
而这些数据在开发阶段同时需要具备被修改的RAM 属性,对照上文我们看到的页的概念,可以自然而然的将页的概念引入进来,然后,FLASH 中的标定数据就称为参考页(Reference Page),RAM中的标定数据就成为工作页(Working Page),参考页就是可以被ECU/XCP读取但不能写入的数据,工作页就是可以被ECU读取/写入,可以被XCP读取和写入的数据,他们在逻辑上都是对应了相同的FLASH地址而被赋予了不同的读写属性。
下边的这个图可以给大家一个更加直观的概念解释,在ECU中的标定数据(标定SEGMENT)里边含有两个页(页0-参考页,页1-工作页),处于标定SEGMENT中有一个标定量为CAL_PID_K,它在链接以后会被分配FLASH地址(位于RP 中),当激活页为RP的时候,这个变量的内容会从FLASH中获得此时为20,然后上位机通过XCP命令让ECU工作于工作页(WP),这个时候这个变量的内容会从RAM中获得此时为15,同时由于数据都从RAM中获得,这个时候如果更改了RAM中的数据,相应的应用到算法上的变量CAL_PID_K也会相应的变化,从而实现了在线标定。
上边介绍了在线标定所使用的基本原理,这时候,聪明的你可能已经看出来,这里有一个最不可思议的点,怎么用相同的地址来在不同的情况下访问RAM或者FLASH呢。
解决这个
难题主要的手段是通过地址映射来将本来链接时候固定下来的变量地址(我们称为逻辑地址)在不同的激活页的情况下映射到不同的物理地址上,有两种方案来实现这个映射,这两种方案和ECU所使用的主控芯片有关,我们来逐一介绍一下。
1.硬件实现地址映射
目前有很多支持硬件实现地址映射的芯片,例如PowerPC系列(MMU模块),TriCORE 系列(Overlay 模块),如果你的ECU选取了这类芯片作为主控芯片,那么我们就可以很简单的通过配置几个寄存器实现地址映射即页切换。
这种方式的好处是,控制逻辑在访问标定变量的时候不需要做任何软件的转换和干预,使用起来简单方便,软件好维护,缺点是,带有这种功能的芯片价格都偏高。
2. 软件处理地址映射
如果处于成本考虑,你的ECU的主控芯片并没有硬件的地址映射模块,那么必须通过一些软件干预的形式实现这个功能,具体我们来看下边这个图,标定变量在实际编译的时候会放置在FLASH区域(图中绿色实线箭头),而当激活WP以后,标定变量的内容会从RAM 区域的WP去获取,而获取的方式是通过在访问变量的时候增加一个偏移量实现的。
举例来说,我们有个字节型的控制变量current等于一个可标定的阈值,那么使用的时候可以这样写current = (uint8_t)((uint32_t)CAL_Current + offset),这个offset就是软件地址转换的核心,当激活RP的时候,该offset = 0,标定变量的地址实际指向0x000到0x200范围内,而激活WP的时候offset就可以设置为0x1000,那么current在获取标定数据的时候就自动在地址上增加了该偏移量,从而指向0x1000到0x1200区域。
这种方式的优点是,可以
适用于任何芯片,缺点也显而易见,需要在访问标定数据的时候增加偏移量,会增加软件的维护工作量。
五、XCP协议和A2L文件– DAQ 同步数据传输详解
这一篇文章,我们主要来讨论一下XCP的同步数据传输,以DAQ(即ECU向PC发送数据,实现数据采集)为例讨论其中所涉及到的重要概念和原理。
如何实现对ECU中的数据进行获取并发送呢,不难想到,只要通过数据的地址和数据的长度就可以完整的获得数据的内容,其实XCP也是基于这么一个简单的原理,XCP在获取到上位机发来的一系列的地址+长度的组合以后完成DAQ的初始化,然后就可以定期的将对应的这些数据发送出来。
一个完整的DAQ数据采集流程有两个步骤:
1. 上位机发送数据的地址长度等信息给ECU做采集前的初始化
2. ECU在做完初始化以后,周期性的把数据发送出来
本篇文章要讨论的是第二点,第一点使用的命令和第二点不同,在后续的文章中会有介绍。
经过前边的介绍,我们可以看出实现周期的数据上传,需要有一个数据结构来维护发送数据的地址和长度,这个数据结构在XCP中称为ODT(Object Description Table),该结构中的每一个条目代表一个数据所处的地址和它的长度,XCP中称之为ODT Entry。
从软件实。