引言
伴随着技术不断进步以及驾驶员对车辆需求点不断增多(自动化、智能化、人性化、舒适化、娱乐化……),为满足这些需求而增加的车内节点数目也在逐年增多(现在高档车ECU数目100+)。与此同时,也给售后维修带来极大的困扰:在车辆进行保养以及维修时,怎样可以快速界定发生故障的部位?这样方便更换或者维修该部件。
本文分享的主题Service 19用于解决该问题,通过定义具体故障为一个具体的DTC,通过Service 19子服务读取所需的DTC状态信息和其他与故障相关的内容(快照信息 or 存储类数据)。由于Service 19所涉及内容极多,汉子分多篇文章描述其内容。
本篇文章重点分享DTC含义、判定DTC产生机制、Service 19 02实现机理等内容,具体从以下几个方面分享:
- UDS协议对服务的定义
- 用图形说明Service 19
- CDD数据库编辑
- 手动测试
- CAPL
UDS协议对服务的定义
UDS协议对Service 19开篇有云:
This service allows a client to read the status of server resident Diagnostic Trouble Code (DTC) information from any server, or group of servers within a vehicle.
人话讲就是:
允许外部诊断仪(Client)通过该服务读取存储在ECU芯片内存中的故障码(DTC)状态信息。
通过Service 19以及对应子服务,可以实现如下功能:
——检索与Tester端定义的DTC状态掩码匹配的DTC数量/DTC列表;
——检索与Tester端定义的DTC相关联的DTC Snapshot数据(有时称冻结帧:DTC快照时与DTC相关联的特定数据记录,存储在ECU端的内存中。DTC快照信息的典型用法时检测到系统故障时,存储当前环境信息。该功能目的在于简化技术人员的故障隔离过程。
——检索与Tester端定义的DTC和状态掩码组合相关联的DTC ExtendedData,该数据的典型用法是存储与DTC相关的动态数据。比如发生故障次数、线路老化次数等
……
对应DTC,一个具体的DTC故障码与一个特定的故障类型,比如说电压异常就分为:
A:低于ECU正常工作电压;
B:高于ECU正常工作电压。
因此是对应两个DTC故障码。
在ISO 14229协议中关于Service 19 02格式:
响应格式:
自己作图讲这个请求与响应格式显示:
其中涉及到的DTC状态位,其作用是现实出DTC对应的状态,如上图中解释:
- SM:请求时的DTC状态位,表示测试人员想要获取控制器中那些状态位被置1,在请求中将这个状态位置1,并发送;
- SAM:在控制器诊断需求规范中,OEM会定义控制器支持那些状态位被置1;
- Status:表示响应中DTC当前实际状态位。
关于DTC Status具体含义以及触发条件,可参看如下文章:
用图形说明Service 19(微信公众号文章,可查询)
接下来用图形表述两方面内容;
A:DTC判定机制
诊断请求与响应
一个DTC对应一个具体故障,而鉴于整车运行是一个复杂的运行环境,其中必不可少会出现电压、电流异常(电涌)、信号不稳定(受电磁干扰)等情况。而对于车内节点判定DTC时,必然会根据一定的判定机制,避免因偶发而导致故障界定不准确:
例如定义一个机制:
- 定义一个Counter;
- 在一定的周期,待测节点没有收到与之进行数据交互节点的报文,该Counter +5;
- 若收到与之数据交互节点的报文,该counter -3;
- 当Counte >=25时,界定与待测节点进行数据交互的节点丢失(Lost communication with XXX)
如下是通过代码表述其逻辑,从而避免了偶发事件影响测试结果。
TMR_CALLBACK_FUNC (CAN_DTC_REC_LOST_BCM)
/*----------------------------------------------------------------------------------------------*/
{
static T8U BCM_BCAN_1_Count = 0;
static T8U BCM_BCAN_4_Count = 0;
BCM_BCAN_1_Count++;
BCM_BCAN_4_Count++;
if(Power_Mode_DTC_
else
{ Statue(DIAG_DTC_LOST_COMM_BCM))
{
if(TRUE == CAN_DTC_GET_BIT_TEST_NOT_COMPLETE(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode))
{
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].StartLoop <= 5)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].StartLoop ++;
}
CAN_DTC_CLR_BIT_TEST_NOT_COMPLETE(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp != DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DiagDescDTCData[(DIAG_DTC_LOST_COMM_BCM + 1)*4] = DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus;
NVM_WriteItem(NVM_OBJ_HANDLE(PrimaryNVM), NVM_IID_PRIMARYNVM_DTC_LOST_COMM_BCM);
}
}
}
if((TRUE==CAN_BCM_BCAN_1_LOST)||(TRUE==CAN_BCM_BCAN_4_LOST))
{
if((BCM_BCAN_1_Count%1==0&&TRUE==CAN_BCM_BCAN_1_LOST)||(BCM_BCAN_4_Count%5==0&&TRUE==CAN_BCM_BCAN_4_LOST))
{
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop < 25)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop += 5;
}
else
{
CAN_DTC_SET_BIT_TEST_FAIL_SINCE_LAST_CLR(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
CAN_DTC_SET_BIT_TEST_FAIL(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
CAN_DTC_SET_BIT_TEST_FAIL_OPERA_CYCLE(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
CAN_DTC_SET_BIT_TEST_FAIL_CONFIRMED(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccLoop = 0;
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp != DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DiagDescDTCData[(DIAG_DTC_LOST_COMM_BCM + 1)*4] = DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus;
if(DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTC_Occurance_Counter<0xFF)
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTC_Occurance_Counter++;
NVM_WriteItem(NVM_OBJ_HANDLE(PrimaryNVM), NVM_IID_PRIMARYNVM_DTC_LOST_COMM_BCM);
}
}
}
}
else
{
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop >= 3)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop - 3;
}
else
{
// CAN_DTC_CLR_BIT_TEST_FAIL_SINCE_LAST_CLR(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
CAN_DTC_CLR_BIT_TEST_FAIL(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
// CAN_DTC_CLR_BIT_TEST_FAIL_OPERA_CYCLE(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].ErrLoop = 0;
// DTCRecordData.DTCData[DIAG_DTC_SPEED_ABNORMAL].DTCWorkFlag = TRUE;
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccOnOffFlag == TRUE)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccOnOffFlag = FALSE;
if((FALSE == CAN_DTC_GET_BIT_TEST_FAIL(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode))&&
(TRUE == CAN_DTC_GET_BIT_TEST_FAIL_CONFIRMED(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode)))
{
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccLoop < IG_CLEAR_HISTORY_DTC)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccLoop ++;
}
else
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccLoop = 0;
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTC_Occurance_Counter = 0;
CAN_DTC_CLR_BIT_TEST_FAIL_CONFIRMED(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);
CAN_DTC_CLR_BIT_TEST_FAIL_SINCE_LAST_CLR(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode);//add in 11June.2013
}
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTC_Age_Count_Value = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].AccLoop;
//DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
//NVM_WriteItem(NVM_OBJ_HANDLE(PrimaryNVM), NVM_IID_PRIMARYNVM_DTC_LOST_COMM_BCM);
}
}
if(DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp != DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode)
{
DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCodeTemp = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus = DTCRecordData.DTCData[DIAG_DTC_LOST_COMM_BCM].DTCCode;
DiagDescDTCData[(DIAG_DTC_LOST_COMM_BCM + 1)*4] = DTC_Status[DIAG_DTC_LOST_COMM_BCM].DTCStatus;
NVM_WriteItem(NVM_OBJ_HANDLE(PrimaryNVM), NVM_IID_PRIMARYNVM_DTC_LOST_COMM_BCM);
}
}
}
}
}
从车内引出一个ECU并显示出三个DTC实际状态位
Tester
0x0A9B17 status of DTC 0x24 (0010 0100)
0x25221F status of DTC 0x60 (0110 0000 )
0x510801 status of DTC 0x2F (0010 1111)
如上示意图,车内ECU当前有三个DTC以及对应的状态位。
这个时候Tester以Service 19 02 84发送至ECU;
对于ECU响应的处理逻辑是Status掩码与DTC实际Status按位“与”操作,不等于0,就将该DTC通过响应显示出来。
因此本例中响应为:
CDD数据库编辑
1、DTC显示方式
在数据库中
DTC显示不同对应不同协议,如下在CANdelaStudio中是以ISO 14229显示:
还有另外一种显示方式,对应协议是ISO 15031-6显示格式:
勾选SAE后显示如下:
需要注意:这个表示内容实质是一致的,只是显示方式不同而已。
2、在CANdelaStudio中DTC批量化导入
新项目新建CDD文件(基于CDDT),对于DTC数量很多时,可以通过CANdelaStudio先导出工具支持的Excel格式文件,再将项目中的DTC在Excel中编辑后再导入CANdelaStudio工具中实现批量化导入。
第一步先导出CANdelaStudio工具支持的Excel格式文件:
第二步再Excel上编辑:
第三步将编辑好的Excel文件导入:
CAPL
关于Service 19 02服务,我以如下Demo做测试:
void MainTest ()
{
byte readDTCByStatusMask[3]={0x19,02,09};
handle =CanTpCreateConnection(0);
CanTpSetTxIdentifier(handle,0x610);
CanTpSetRxIdentifier(handle,0x612);
CanTpSendData(handle,readDTCByStatusMask,3);
testWaitForTimeout(2000);
}
在Trace中显示:
愿你我相信时间的力量,
做一个长期主义者!
本文暂时没有评论,来添加一个吧(●'◡'●)