UDS结合实例——DTC执行的逻辑和DTC的存储

开篇总述:

DTC的结构和基本信息之前一篇文章就讲解过,如何理解汽车诊断中的,诊断故障代码DTC_dtc故障码-CSDN博客,不过对DTC的执行逻辑和存储策略讲的不是很清晰,于是专门来讲清楚。

1、DTC执行的逻辑

规范中的这个图就非常直观的显示了DTC的执行逻辑:

x轴主要是时间信息,已经在下图标注了一个完整的Operation Cycle的时间周期。 主要关注Y轴,我们从上往下看:

1.1、Operation Cycle

操作循环,大致等于很多资料中说的“点火循环” ,我所知道的大部分的DTC的“操作循环”=“点火循环”,点火循环的意思就是key="OFF"->"ACC"->"ON"->"CRANK"->"OFF",如果不理解,先记住即可。

1.2、Test Sample

测试采样点:"Test Sample",了解这个概念之前。我先举个比较简单的实例:

报文0x110丢失DTC (U1 22 12),在检测前提条件满足的情况下,CDD或诊断调查表中会描述:“连续500ms未检测0x110报文则报出0x110丢失DTC (U1 22 12)”。这里假设0x110发送周期为100ms。

那500ms内,查询几次0x110报文接收的状态,就是“Test Sample”

接着玩下看: 

1.3、"Fault detected at moment of test run"

错误在测试运行中被检测到、 "Fault not detected at moment of test run"错误未在测试运行中被检测到。可以看到这两个检测的频率之和="Test Sample"检测频率。也就加深了我们对"Test Sample"的理解,即“在每一个 "Test Sample"  中必须得出一个测试的结果,错误被发现或没有错误”

1.4、“Fault Detection Count

”错误检测计数,有分为两个参数:如下

1、prefailed:预定义错误计数,这个值为(0-127),这里有一个问题,每次错误被检测到错误计数+多少的问题?

答:这个是主机厂或供应商自己定义的,下图可参考

我们来计算一下   连续10次检测失败,则 128/10=12.8,商取整数=13。则每次检测到错误,prefailed +13。

2、prePassed:预定义通过计数,这个值为(-128,0) ,这个值没检测到一次通过,prePassed+(-13)

小结:

1、两种参数的变化是独立的,没有线性的关联关系。一种参数只能连续自增或自减。当自增、自减被中断会直接被重置为0。

继续往下看:

1.5、testFailed 初始值00

 testFailed=01的判断条件其实,只有一条当prefailed >=127时,testFailed =01、当prefailed<127时,testFailed =00。

不过还存在几种特殊情况,

(1)当本次操作循环结束后,到下次操作循环开启时,testFailed会被初始化为0。

(2)0x11服务,复位后,testFailed也会被初始化,同理断电上电也会被初始化!

1.6、testFailedThisOperationCycle

初始值00

就是本次操作循环中,只要触发一次prefailed >=127,该位就会一直置位=01。

不过还存在几种特殊情况,

(1)当本次操作循环结束后,到下次操作循环开启时,testFailed会被初始化为0。

(2)0x11服务,复位后,testFailed也会被初始化,同理断电上电也会被初始化!

1.7、pendingDTC

默认初始值00 ,挂起DTC,结语当前DTC和确认DTC之间的一种DTC形态,这有涉及到DTC存储策略中的另外一个计数器参数“Occurrence Counter”,错误发生计数,详情下文会在讲解DTCExtented中讲解。但是具体Occurrence Counter=多少时,可以由主机厂或供应商自行决定。

注意pendingDTC的状态,并不会再“操作循环结束后重置”,也不会因为0x11复位,或重新上下电而被重置!!

1.8、Confirm DTC

默认初始值00,确认DTC,同样和,DTC存储策略中的另外一个计数器参数“Occurrence Counter”,错误发生计数有关。

注意pendingDTC的状态,并不会再“操作循环结束后重置”,也不会因为0x11复位,或重新上下电而被重置!!

1.9、testNotCompleteSinceLastClear:

“自从上次清除后,测试未完成”,这里的概念可以分为两个部分理解 :

(1)“测试完成”或“测试未完成”的概念,判断标准只有prePassed<128,或prefailed >127,时认为测试完成。

(2)“上次清除”中的“清除”概念,这个概念比较复杂,首先我们知道prePassed和prefailed是必须连续变化的,只要计数中断后,立即=0,例子如下:prePassed先自增到-110,然后立即prefailed自增到5,此时prePassed立即=0。

结合理解;即prePassed或prefailed被重置为0后,prePassed或prefailed还没有达到阈值。

不过还存在几种特殊情况,

(1)当本次操作循环结束后,到下次操作循环开启时,testFailed会被初始化为0。

(2)0x11服务,复位后,testFailed也会被初始化,同理断电上电也会被初始化!

1.10、TestFailSinceLastClear

prePassed或prefailed被重置为0后,prefailed还没有达到>127的阈值。

不过还存在几种特殊情况,

(1)当本次操作循环结束后,到下次操作循环开启时,testFailed会被初始化为0。

(2)0x11服务,复位后,testFailed也会被初始化,同理断电上电也会被初始化!

1.11、testNotCompleteThisOperationCycle

测试未完成,在这个操作循环中,初始默认值为0x01,这个很好理解,此操作循环中prePassed或prefailed还没有达到阈值,就认为是测试未完成。

1.12、思考问题?

如果你有耐心看到这里,说明你是用心读了,

那么你们心中是不是有个疑问?怎么搞出这么多状态,可能大家实际接触的项目中也基本只支持

testFailed,pendingDTC 和ConfirmDTC,这几种。一般来说其实也够用了。

但是只要我们理解了上文的描述,实际情况可能更复杂:如下

prePassed先递减到-10,然后preFailed开始递增到 150,然后prePassed从0开始又递减到-10,然后,然后preFailed开始递增到 150。这种状态下,明显是错误被检测出来的概率,比测试通过概率大的多,但是确不会报出任何DTC,以及任何错误状态下的DTC?,这样合理吗?明显是不合理的。

于是我们使用testNotCompleteSinceLastClear这个服务,就能够检测到这种错误

1.13、补充一个DTC老化的逻辑

       “DTC老化”,我觉得这个翻译不太好,有些资料把DTC老化叫做"DTC的自恢复",个人觉得这种翻译说法更接近于实际意义。

       DTC老化的解释:系统中已经检测到一个ConfirmDTC了,但是后续,在满足检测条件的前提下,100个操作循环中,都没有检测到该DTC,那么这个DTC是否还有存在的必要?DTC老化就是这个意思。即固定的检测环境下,对特定类型的DTC(一般都是ConfirmDTC),一个操作循环中,没有检测到DTC,则老化计数自动加上一个“固定值”。当连续若干个操作周期内都没有检测到错误后,老化计数器>设定的一个值后。DTC被清除(连带该被清除的DTC相关的快照和拓展信息全被除)。

规范中并没有规定,老化计数自动加上一个“固定值”这个固定值的大小,只是必须是正整数(不包括0),一般都是+1。

连续检测的意思是,如果出现中断,就是指中间掺杂了一个检测到DTC的操作周期后,老化计数会被重置,一般都是重置为0.

2、DTC的存储逻辑

2.1 、DTC自身存储位置,存储大小

DTC是必须要存储在非易失性的存储器中,存储大小,具体看协议类型,uds是基于14229大小固定为3个字节。

2.2 DTC的Statues

我们在使用大部分的0x19子服务时都会根据“状态掩码”来读取合适的DTC,肯定响应也会给出该DTC的“状态码”,故对应DTC的状态码也是需要存储的,且映射到具体的DTC。

2.3 DTC的Snapshot

也就是DTC对应的映射信息,具体记录那些信息,诊断规范并没有定义,主机厂和供应商可自行决定。

举例说明,加入 C0 03 15是代表速度传感器通信故障,供应商和主机厂通常会将故障发生时的速度信息,电压信息,车辆上下颠簸的加速度信息记录下来。如果每次DTC出现时,车辆都具有速度,且车辆颠簸比较厉害,通过快照信息就可以大致推断出,速度传感器的供电线束或通信线束是不是链接不稳定。

小结:快照信息是对DTC故障分析、维修的重要信息补充说明

2.3 DTC的Severity严重度

很容易理解DTC的严重度。车速传感器故障的严重度,和车窗位置传感器故障的严重度,显然不是一回事。故对DTC的严重度作出等级划分也是非常有必要的。

严重度也分为两个参数,1严重度掩码参数,注意只能适用于diagrequest报文中,2严重度记录数据,只能在diagResponse中使用。

数据结构如下

可以看到DTCSeverity,固定为7个bit,即1个Byte,【bit7-bit5】是可选的,图片显示的是DTC严重度信息(可选),这部分仅仅是起到提示的效果,且规范对每一位的意思作出了规定。一起来看

前几位指示了,该DTC引发的故障对驾驶员或维修人员的一个建议,实例举例,如车窗传感器故障,设计严重度码时,bit7(需立即检查)就不需要使用了。如果是车速传感器故障,建议使用bit7或bit6置位。

DTCClassInformation:DTC等级信息,根据规范中的描述

 2.4 DTC Format Identifier

我们知道根据诊断协议的不同,DTC的格式也是不一样的。DTC Format Identifier(DTC格式标识符)的目的就是指示了,DTC的格式。

0x19 服务中的01服务中的诊断回复信息,就存在DTC Format Identifier信息,在回复报文的第4个Byte。

DTC Format Identifier,的大小固定为1个字节,位定义也是14229定义好的,如下图

2.4 DTCCount[]

DTC数量的统计,如下图在 0x19 01 /07时,回复信息的第5byte和第6byte,构成了DTC数量的描述。需要注意,编码采取了Motorol编码格式,高位在前,低位在后。

有杠精说,如果符合要求的DTC,存在0x FFFF+0x01个,怎么办?那你赢了,按照现在的规范,确实解决不了这样的问题

 

 2.5 SnapShot 快照相关的参数

(1)DTCSnapshotRecordNumber,快照记录编号。

这个也很好理解,一个DTC,被记录了两次,同样的也会记录两次快照信息,如果不对快照信息编号,就会很麻烦。

DTCSnapshotRecordNumber,大小固定为1Byte。规范没有对bit作出定义,一般采取十六进制递增来表示。第一次记录的快照信息编号为00,第2次快照信息编号为01.以此类推。。。

(2)DTCSnapshotRecord快照信息记录,此部分还分为两个部分

 

dataIdentifier分为两个字节,大小固定,数值主机厂或供应商自行定义

snapshotData :需要注意的是字节大小不固定,包含那些信息不固定,都是主机厂或供应商自行定义。

快照具体记录的信息,必须是通过DTC来实现

2.6 ExtendedData拓展数据相关的参数

(1)DTCExtendedDataRecordNumber:拓展数据记录编号,和快照数据记录编号一样,拓展数据也是要依靠具体的DTC来存在的。也是对DTC信息的补充说明。但是和快照数据记录编号不一样的是,拓展数据记录编号不仅仅只是为数据编号,而且还简介定义了后续相关数据的类型等。

DTCExtendedDataRecordNumber:固定为1个Byte,规范开放给主机厂或制造商的0x01-0x8F

理论上来说

如  DTCExtendedDataRecordNumber=01,代表错误发生计数,也就是DTC被检测出来的次数!

     DTCExtendedDataRecordNumber=02,则代表着老化计数的数值。

### 如何使用UDS协议读取DTC快照数据 #### 请求格式 为了读取特定DTC的快照信息,需构建一个遵循UDS标准的服务请求。该请求应包含两个主要参数:`DTCMaskRecord` `DTCSnapshotRecordNumber`[^4]。 - **DTCMaskRecord**: 此字段指定要查询的具体故障码(DTC),通常是一个三字节编码。 - **DTCSnapshotRecordNumber**: 表示所需获取的数据组编号;此值可以从0x01到0xFE之间选取,而0xFF则代表请求所有可用的快照记录。 当向车辆电子控制单元(ECU)发送上述配置的消息后,如果存在相应的快照数据,则ECU会返回这些数据连同它们的状态信息一起反馈给客户端设备。然而,假如不存在任何与所请求DTC关联的快照资料或是输入了一个无效的记录号时,ECU将会回复错误代码(NRC)31 (request out of range)[^3]。 以下是Python脚本的一个简化版本,展示了如何利用SocketCAN库实现这一过程: ```python import can def read_dtc_snapshot(dtc, record_number=0xff): bus = can.interface.Bus(bustype='socketcan', channel='vcan0') arbitration_id = 0x7df # UDS request ID message_data = [ 0x19, # Service identifier for Read DTC Information 0x04, # Subfunction code to indicate reading snapshot by DTC number and record number *dtc.to_bytes(3), # Convert the provided DTC into a three-byte sequence as required by the protocol record_number # Specify which set(s) of snapshots we want; default is all sets. ] msg = can.Message(arbitration_id=arbitration_id, data=message_data, is_extended_id=False) try: bus.send(msg) response = bus.recv(timeout=1.0) if not response or len(response.data) < 8: raise Exception("No valid response received.") status_code = response.data[1] if status_code != 0x59: # Positive acknowledgment from ECU error_msg = f"Error occurred while trying to retrieve snapshot ({status_code:#04x})" raise Exception(error_msg) print(f"DTC Snapshot Data Received:\n{response}") finally: bus.shutdown() read_dtc_snapshot(int('C00FFEE', base=16)) ``` 这段程序尝试连接至虚拟CAN总线(virtual CAN interface),并向目标节点发出一条命令以提取指定DTC的所有快照记录。请注意,在实际应用环境中可能需要调整通信接口设置以及处理更多异常情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值