UDS tester之Tdrm

本文介绍了UDS Tester的工作原理,包括其内部状态机定义、四个关键定时器的作用及Tdrm的工作流程。并探讨了Tdrm在实际应用中的局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UDS testerTdrm 

2018-1-16

        Tdrm叫做 tester diagnostic request manager,或者叫做诊断请求测试管理器,今天以vectorTdrm为例,研究下它的工作流程。

一、Tdrm的作用

        如果你在做汽车ECU,那么当做诊断服务的时候一定会用到UDS,而如果恰好你所开发的ECU也有诊断其他ECU的需求,那么就一定会用到tester端软件。Tester可以调用TP层,向其他ecu发起诊断请求,实现全车诊断、ECU软件刷写的功能,十分有用。它也可以处理ecu的反馈,供用户层使用。

二、一个状态机,四个timer

        先看下内部状态机的定义,tester一共定义了8个状态,空闲状态默认会话下的空闲状态(用于查询当前是否可以进行诊断操作,只有在idle的条件下才可以发起下一次诊断)诊断请求发送过程中;等待请求发送完成;等待ecu应答;接收进行中(无请求的接收)请求接收结果接收中等待下一次进入idledelay

typedef enum _tTdrmState

{

  kTdrmStateIdle,                  /* System in idle state */

  kTdrmStateIdleSessionActive,    /* System session is active (just for TdrmGetStatus() when in idle mode) */

  kTdrmStateTxInProgress,         /* Temporary state while sending data */

  kTdrmStateWaitSendReqConfirm, /* Request issued to TP. Waiting for confirmation */

  kTdrmStateWaitEcuResponse,   /* Service successfully transmitted to ECU. Wait for ECU response */

  kTdrmStateRxInProgress        /* Temporary state while receiving data */

  kTdrmStateWaitRxInProgress    /* Temporary state while receiving data */

  kTdrmStateWaitIdle             /* Temporary state after a transmission */

} tTdrmState;

        四个timer P2, P2Star, S3, P3

        P2: 客户端请求到ECU的响应时间, typical 100ms

        P2Star: 增强延时时间,当client收到 0x78的否定响应时,会多延长一会等待时间,典型值为 5000ms

        S3:client发送两次test present3E,00)的间隔。

        P3:在没有应答的条件下,两次请求之间(从第一次请求timeout到第二次请求发出)插入的延时时间。

三、Tdrm的工作流程分析

        下面用一张图表示这几个状态是如何转换的:

 

        (1)tester 初始化

        Tdrm 正常工作前应该首先调用TdrmInitPowerOn()来初始化状态机用到的几个timer,根据当前MCU执行的周期,计算出所有时间参数对应的循环数量调用TdrmInit()来初始化状态机到idle状态,关闭定时器以及清除请求标志等,此时状态机停留在S1状态。需要周期性调用TdrmTask(),来推动状态机转换。

        (2)tester 发送请求

        当应用层调用TdrmServiceRequest()来请求某一个服务时,此时App需要把请求服务的数据字和长度填充好,再调用TP层将数据发送出去;此处就直接返回发送成功,之后就就进入等待ECU应答的S4状态。与此同时,TP发送完请求后会调用CanTp_NUSDataIndication进而调用TdrmSendConfirm,这里会判断这个请求是否需要ecu应答,如果需要就进入到S5状态,如果不需要应答肯定响应,就进入S8,继而回到S1 idle状态。

        (3)tester 接收响应

    在S5 等待ECU应答状态下,会启动一个定时器P2,如果在规定的时间内TP收到了SF或者FF,那就会调用TdrmPrepareReception,使其进入到S7也就是等待接收过程中;如果接收完成或这接收失败都会重新回到S1。如果在规定的时间内没有收到任何应答,待P2超时后回到S1,此时重试次数减一,重置P2,待进行下一次重新发送。

        (4)tester 维持会话

        作为client端,请求服务器进入非default session后,如果没有请求,要周期发送tester present报文来保持会话,如果应用层发起了其他请求从而使状态机进入非idle状态后,就不需要发送tester present报文了。

四、Tdrm的局限性

        在这个架构下是无法多路并发的。不过在实际的情况下,如果需要诊断总数不多的ecu,一般的做法是轮询,但如果所在ecu需要诊断、刷写的ecu比较多,论询是非常耗时的,如果能把这个过程与ecu之间的诊断或刷新顺序进行解偶,同时对多个ecu进行操作,就可以极大提升诊断或刷写速度了。

### DTC的定义与结构 在UDS协议中,DTC(Diagnostic Trouble Code,诊断故障代码)用于标识车辆电子控制单元(ECU)中检测到的故障。DTC通常由三个字节组成:DTC High Byte(高字节)、DTC Middle Byte(中字节)和DTC Low Byte(低字节)。对于UDS DTC(ISO 14229),前两个字节根据DTC Format Identifier(如0x00或0x04)进行解码,而最后一个字节则根据SAE J2012-DA Failure Type Byte (FTB) 表进行解码。OBD DTC(ISO 15031)则使用两个字节,并根据SAE J2012-DA进行解码[^2]。 ### DTC判定机制 当ECU检测到故障时,会通过特定的判定机制来判断该故障是否达到了产生DTC的条件。这些条件通常包括故障持续时间、发生频率等。一旦满足条件,ECU会将DTC及其状态(Status)存储在其内存中。例如,如果某个传感器信号超出正常范围,并且这种状态持续了一定的时间,ECU就会记录一个DTC。DTC的状态信息可以帮助技术人员了解故障是否是当前发生的,还是过去发生的但尚未清除的情况[^1]。 ### DTC状态信息 DTC的状态位(Status)提供了关于故障状态的详细信息,包括故障是否当前存在、是否已确认、是否已测试等。这些状态信息对于诊断和维修非常重要,因为它们可以帮助确定故障是否仍然存在,或者是否已经修复。例如,如果一个DTC的状态位显示故障已确认且已测试,但不再存在,则可能表明问题已经解决,但仍需要进一步检查以确保没有遗漏的问题。 ### DTC的读取与处理 通过UDS协议,可以使用特定的服务(如0x19服务)来读取DTC信息。这些服务允许诊断工具从ECU中检索DTC及其状态信息。例如,0x19 0x02子服务可以用来读取所有DTC的快照数据,而0x19 0x04子服务可以用来清除DTC。在实际应用中,技术人员可以使用这些服务来诊断车辆故障,并采取相应的处理措施,如更换故障部件或重新配置软件设置。 ### 示例代码 以下是一个简单的Python示例,展示如何通过UDS协议读取DTC信息: ```python def read_dtc(ecu_connection): # 发送0x19 0x02请求读取所有DTC的快照数据 response = ecu_connection.send_request([0x19, 0x02]) if response: # 解析响应数据 dtc_list = parse_dtc_response(response) return dtc_list else: return [] def parse_dtc_response(response): # 假设响应数据中的每个DTC由4个字节组成 dtc_list = [] for i in range(0, len(response), 4): dtc_bytes = response[i:i+4] dtc_high = dtc_bytes[0] dtc_mid = dtc_bytes[1] dtc_low = dtc_bytes[2] status = dtc_bytes[3] # 根据DTC Format Identifier解码DTC dtc_code = (dtc_high << 16) | (dtc_mid << 8) | dtc_low dtc_list.append({'dtc': dtc_code, 'status': status}) return dtc_list # 假设的ECU连接对象 class ECUConnection: def send_request(self, request): # 模拟发送请求并接收响应 print(f"Sending request: {request}") return [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77] # 模拟响应数据 # 创建ECU连接并读取DTC ecu_conn = ECUConnection() dtcs = read_dtc(ecu_conn) for dtc in dtcs: print(f"DTC: {dtc['dtc']}, Status: {dtc['status']}") ``` ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值