本文分享的主题Service 19用于办理该问题,通过定义详细故障为一个详细的DTC,通过Service 19子做事读取所需的DTC状态信息和其他与故障干系的内容(快照信息 or 存储类数据)。由于Service 19所涉及内容极多,男人分多篇文章描述其内容。
本篇文章重点分享DTC含义、剖断DTC产生机制、Service 19 02实现机理等内容,详细从以下几个方面分享:
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中显示:
愿你我相信韶光的力量,
做一个长期主义者!