小猫爪:嵌入式小知识17-XCP on CAN简介
- 0 目录
- 1 前言
- 2 XCP on CAN
- 3 实战演练
- 3.1 CONNECT
- 3.2 GET_COMM_MODE_INFO和GET_STATUS
- 3.3 GET_SEED和UNLOCK
- 3.4 获取Slave信息
- 3.5 SET_MTA和BUILD_CHECKSUM
- 3.6 设置DAQ
- 3.7 DAQ传输
- 3.8 SHORT_UPLOAD
- 3.9 标定
- 3.10 FLASH Program
- END
0 目录
- 小猫爪:嵌入式小知识15-XCP基础简介
- 小猫爪:嵌入式小知识16-XCP协议简介
- 小猫爪:嵌入式小知识17-XCP on CAN简介
1 前言
前面已经对XCP协议做了非常细致的介绍,接下来就来看看XCP是怎样在CAN总线上进行工作的吧。参考资料:XCP协议规范2003。
2 XCP on CAN
XCP在CAN上的实现也是非常的简单,首先得分配两个CAN ID,对于Master这一方来说,一个作为发,即CMD和STIM,一个作为收,即RES/ERR/EV/SERV和DAQ。这里需要注意的是STIM和DAQ可以有自己独立的CAN ID,但是需要使用SET_DAQ_ID命令CMD进行配置。
之前文章里已经提到过,在CAN上的XCP是不支持交互通信模式的,一般都是采用标准通信模式和块传输模式两者配合。
XCP在CAN上的协议包的体现为:
首先XCP Header为空,至于XCP Packet则与XCO协议一模一样。而XCP Tail则根据经典CAN的MAX_DLC(经典CAN的MAX_DLC固定为8)和XCP Packet长度LEN有以下两种情况:
- MAX_DLC = LEN
这个时候XCP Packet把CAN帧的8个字节全部填满,XCP Tail为空。 - MAX_DLC > LEN
这个时候XCP Packet没有把CAN帧的8个字节填满,那么就需要填充到8个字节,这个时候XCP Tail即为填充。
对于CAN-FD,MAX_DLC只有以下值有效:8、12、16、20、24、32、48和64。这个时候有的朋友就要问了,那如果LEN > MAX_DLC的时候怎么办,不可能,这种事情在XCP on CAN上是不可能发生的,你放心吧。
3 实战演练
接下来来看看XCP的一些常用操作在CAN上的体现。当我将CANape配置完之后,点击Start,Master和Slave会进行怎样的交互呢?
具体流程如下:
3.1 CONNECT
首先使用CONNECT命令与Slave建立XCP连接。CONNECT的正响应具体描述如下:
根据上表就可以解析出Flash programming available,stimulation available,DAQ lists available, calibration/paging available,Intel format,AG为BYTE,不支持Slave Block Mode,支持命令GET_COMM_MODE_INFO命令获取通信配置,MAX_CTO = 8,MAX_DTO = 8, 还有协议层和传输层的版本号。
其中Slave Block Mode意思就是说,Slave可以发起块传输,就是连续发送好几个XCP包。而Master Block Mode就是Master可以发起块传输。
3.2 GET_COMM_MODE_INFO和GET_STATUS
再使用GET_COMM_MODE_INFO和GET_STATUS获取Slave的XCP协议信息以及当前XCP运行状态信息。
GET_COMM_MODE_INFO的正响应具体描述如下:
这里就不一一对着解析,稍微说一下一些参数的含义吧:
1.MAX_BS 表示在PGM命令中所运行下载的最大Block大小。
2.MIN_ST表示在块传输过程中,两个XCP包允许相隔的最小时间。
3.QUEUE_SIZE表示在支持交互模式下,Master连续发送CMD的最大数量。
GET_STATUS的正响应具体描述如下:
1.Current session status中表示了一些行为状态,有STORE_CAL_REQ,STORE_DAQ_REQ ,CLEAR_DAQ_REQ,DAQ_RUNNING,RESUME。
2.Current Resource Protection Status中则表示了当前有哪些CMD是被SEED&KEY锁着的。在XCP中,有一种保护机制叫做SEED&KEY保护机制,它会按照功能具体分成了CAL/PAG,DAQ,STIM,PGM四类,如下:
每一类都有一套单独的SEED&KEY机制(算法也可以不同),需要单独解锁,只有使用GET_SEED和UNLOCK进行解锁后,然后才能发送其相对应的CMD。
3.3 GET_SEED和UNLOCK
再使用GET_SEED和UNLOCK命令对所有的CMD进行解锁,GET_SEED命令具体描述如下:
当Mode=0时,第二个字节表示Resource,也就是说这次解锁的对象是哪一类CMD,具体请参考Current Resource Protection Status的描述。
3.4 获取Slave信息
再使用GET_DAQ_PROCESSOR_INFO, GET_DAQ_RESOLUTION_INFO和GET_CAL_PAGE命令获取Slave的DAQ信息,为后面配置DAQ做准备。
GET_DAQ_PROCESSOR_INFO正响应具体描述如下:
- DAQ_PROPERTIES表示当前Slave支持DAQ哪些特征,比方说支不支持动态DAQ_List,支不支持TimeStamp,支不支持更改DAQ的CAN ID,支不支持报告overload(就是一个周期内没有把所有的ODT发送完)以及报告overload的方式。
- MAX_DAQ, MIN_DAQ和MAX_EVENT_CHANNEL在之前文章已经介绍过了,这里就不多做解释了。
- DAQ_KEY_BYTE里面有Type of Optimisation Method,address extension of ODT_Entry, ODT number is Absolute or Relative。
GET_DAQ_RESOLUTION_INFO正响应具体描述如下:
这个命令可以获取当前Slave支持的ODT_Entry的数量和大小,以及Timestamp的大小和分辨率,在这里就不多做解释了,感兴趣的朋友请参考协议规范。
GET_CAL_PAGE正响应具体描述如下:
Logical data page number表示当前(XCP或者ECU,由该CMD中的Mode字节区分)激活的PAGE编号。
3.5 SET_MTA和BUILD_CHECKSUM
再使用SET_MTA设置MTA(Memory Transfer Address)和Address extension,随后使用BUILD_CHECKSUM获取MTA处,大小为6610的Block的Check Sum。
3.6 设置DAQ
接下来就可以设置DAQ了,设置DAQ的过程比较复杂,总的来说,其实就是设置ODT_Entry,设置ODT,再设置DAQ-List,随后再将DAQ与Event Channel绑定,随后再开启DAQ。具体流程如下:
- 当Slave是动态DAQ-List配置时,必须要先使用FREE_DAQ命令清空DAQ-List,ODT,ODT_Entry。
- 再使用ALLOC_DAQ命令创建1个空的DAQ-List,DAQ_LIST_NUMBER为0(依次累加)。
- 再使用ALLOC_ODT命令创建3个空的ODT,并且把这3个ODT加入DAQ_LIST_NUMBER为0的DAQ_List中。
- 再使用ALLOC_ODT_ENTRY命令分别创建3个ODT_ENTRY,并且将其分别放置在上一步创建的3个ODT中,ODT_ENTRY中的Element大小分别是2,6,4个字节。
- 再使用SET_DAQ_PTR命令和WRITE_DAQ命令分别对前几步创建的3个ODT_ENTRY进行配置,配置内容有BIT_OFFSET(数据掩码,表示传输的数据BIT有效位,如果等于FF,则说明忽略掩码),Element的大小(前面得知AG=BYTE,所以这里Element字节大小是2个字节),Address extension,以及Element的物理地址。到这里整个DAQ_List已经设置完毕。
- 再使用SET_DAQ_LIST_MODE命令设置DAQ_List的一些特征,设置Identification Field的格式为relative ODT number and absolute DAQ list number (BYTE),开启DTO的TimeStamp,DAQ模式(Slave–>Master),还有将DAQ_List与Event Channel 2绑定(Event Channel在Slave已经配置好了,这里直接根据Channel Num进行百绑定),至此整个DAQ配置已经全部完成。
- 最后使用START_STOP_DAQ_LIST命令选择DAQ_List 0,使用GET_DAQ_CLOCK获取一下Slave的时间戳,再使用START_STOP_SYNCH开启START_STOP_DAQ_LIST选择的DAQ_List 0的传输。
3.7 DAQ传输
由于在前面配置DAQ中,将DAQ_List与Event Channel 2绑定,而在Slave中,Event Channel 2是一个100ms的周期性事件,所以可以看到DAQ报文每100ms发送一次。
首先DTO包的格式如下:
多帧DTO构成的DAQ格式如下:
根据在上面DAQ配置步骤中,使用了SET_DAQ_LIST_MODE将Identification Field的格式配置为relative ODT number and absolute DAQ list number (BYTE),所以Identification Field的格式为PID为一个字节表示ODT Number,DAQ一个字节表示DAQ-List Number:
根据在上面DAQ配置步骤中,使用SET_DAQ_LIST_MODE命令开启了Timestamp,以及在前面的GET_DAQ_RESOLUTION_INFO得知Timestamp的大小是4字节,编码为Intel模式,所以
拿出一帧数据如下:
红色框:表示ODT Number。
蓝色框:表示DAQ-List Number。
黑色框:分别代表数据部分,分别对应前面配置的2,6,4个字节大小的3个ODT_Entry。
3.8 SHORT_UPLOAD
在之前文章提到过,除了可以使用DAQ进行数据测量,还可以使用Master周期发送CMD去主动读取,这里一般采用的是SHORT_UPLOAD命令去读取。
3.9 标定
- 首先使用SET_MTA命令设置标定数据目标地址。
- 再使用DOWNLOAD命令写入标定值。
- 最后再使用SHORT_UPLOAD命令回读标定值校验是否正确写入。
3.10 FLASH Program
找不到合理素材,先欠着,嘿嘿嘿~来年再见!!!
到这里,XCP就差不多都介绍完了,下期再见。