UDS诊断协议解析理解(10、27、19、2F、31、2E、34、36、37)
这篇文章不是让你死背10 03、22 F1 90、2F 65 03。 我们换一种方式把 UDS 当成一场 tester 和 ECU 的对话。tester 每次开口都在问一件事ECU 要么答应要么说“不行原因是什么”。开场先别背服务码先听懂这场对话想象你拿着诊断仪对 ECU 说话。你不是直接去改内存也不是直接去控制水泵。你要先按规矩敲门我是谁我要干什么我要操作哪个对象我带了什么参数UDS 报文就是这四句话的二进制版本。比如2F 65 03 03 01 50别一上来就慌。按顺序拆2F 我要做 IO 控制 65 03 我要控制 DID 0x6503也就是这个项目里的电机水泵 03 我要做 shortTermAdjustment短期控制 01 50 控制值使能 1速度 0x50也就是 80你看报文不是乱码。它只是很短很挤把一句话压成了几个字节。一条 UDS 请求在车里怎么走在这个项目里物理诊断请求 CAN ID 是0x73C诊断响应 CAN ID 是0x7BC所以 tester 发请求时常见路径可以理解成CAN 收到 0x73C - ISO-TP 判断这是一帧还是多帧 - 拼出完整 UDS 数据 - 诊断层取出 SID - 查服务表 - 检查会话、安全等级、长度、条件 - 调用具体服务函数 - 组正响应或负响应 - 通过 0x7BC 发回 tester这一段特别重要。你后面看任何服务都不要只盯着服务本身。你要知道它一定先经过三层CAN 层这帧是不是给我的 ISO-TP 层这一帧/多帧能不能拼成完整 UDS UDS 服务层这个 SID 能不能执行执行什么怎么回复我理解所有 UDS 服务的固定框架每个服务都用同一套问题去吸收1. 这个服务让 ECU 干什么 2. 它需要什么会话默认、扩展、编程 3. 它需要安全解锁吗 4. 请求报文由哪些字段组成 5. ECU 收到后检查什么 6. 成功时怎么回 7. 失败时用哪个 NRC 回把报文抽象一下UDS 请求就是SID 子功能/动作 目标对象 参数数据对应到常见服务类型目标对象是什么22/2EDID数据标识符19/14DTC故障码2FIO DID被控制对象31RID例程 ID34/36/37地址、大小、数据块10/11/27/28/3E/85多数靠子功能表达动作这就是总钥匙。以后你看到任何服务先找SID 是谁动作是什么对象是谁参数是什么正响应和负响应ECU 怎么说“行”或者“不行”UDS 正响应最简单正响应 SID 请求 SID 0x40比如请求 SID正响应 SID服务1050会话控制1959读 DTC2262读 DID2E6E写 DID2F6FIO 控制3171例程控制3474请求下载3676传输数据3777退出传输负响应统一是7F 原请求 SID NRC比如7F 2F 31意思是你刚才请求的是 2F 服务但是我执行不了原因是 31 requestOutOfRange。常见 NRC 可以这样记NRC人话理解11这个服务我不支持12这个子功能我不支持13你报文长度或格式不对22当前条件不满足24顺序错了31对象或参数超范围33安全等级不够35key 错36解锁错误次数超了37延时没到70下载请求不接受72编程失败73数据块序号错78我正在处理等一下7E当前会话不支持这个子功能7F当前会话不支持这个服务92电压过高93电压过低第一组先拿到“进门资格”0x10 DiagnosticSessionControl切换会话10服务像是在问 ECU我现在想进入某种工作模式可以吗常见子功能子功能含义01默认会话02编程会话03扩展会话比如请求进入扩展会话10 03逐字节看字节含义10DiagnosticSessionControl03请求 extendedDiagnosticSession如果 ECU 同意会回50 03 00 32 00 C8解释字段含义5010 的正响应03已进入或接受扩展会话00 32P2Server 时间00 C8P2*Server 时间很多服务不是默认会话就能用比如2F通常要扩展会话刷写相关服务要编程会话。所以10是很多诊断流程的第一步。常见失败7F 10 12 子功能不支持 7F 10 22 当前条件不满足 7F 10 7E 当前会话不允许切换到目标会话0x27 SecurityAccess解锁权限27服务像是在说我要做敏感操作你先证明你有权限。它是两步走1. tester 请求 seed 2. ECU 返回 seed 3. tester 根据 seed 算 key 4. tester 发送 key 5. ECU 校验 key正确就提升安全等级Level1 常见请求27 01响应67 01 seed16...然后 tester 发 key27 02 key32...如果 key 正确67 02这个项目里Level1 常用于扩展会话下的写 DID、IO 控制等。Level4/FBL 常用于编程刷写。常见失败7F 27 24 没有先请求 seed或者请求顺序不对 7F 27 35 key 错 7F 27 36 错误次数超限 7F 27 37 延时没到一句话记住10 负责换房间27 负责拿钥匙。第二组读写 ECU 数据0x22 ReadDataByIdentifier读 DID22服务是最常见的读数据服务。tester 问 ECU你把某个 DID 对应的数据给我看看。请求格式22 DID_H DID_L例子读 VIN 类 DIDF19022 F1 90正响应62 F1 90 data...解释字段含义6222 的正响应F1 90回显 DIDdataDID 数据它也可以一次读多个 DID22 F1 90 F1 A1响应就按顺序拼62 F1 90 data1... F1 A1 data2...在这个项目里常见 DID 有DID类型F183/F187/F18A/F18E/F191/F195版本、零件号、软件硬件信息F190VIN 类数据F1A1自定义配置数据DF01-DF06DTC 快照相关 DID失败时通常是7F 22 13 长度错误 7F 22 31 DID 不支持 7F 22 33 权限不够0x2E WriteDataByIdentifier写 DID2E是22的兄弟。22是读2E是写。请求格式2E DID_H DID_L data...比如写F1902E F1 90 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37解释字段含义2EWriteDataByIdentifierF1 90要写的 DID后面 17 字节写入 F190 的数据正响应只回显 DID6E F1 90这个项目里常见可写 DIDDID长度条件F1849编程会话Level4F19017扩展会话Level1F1A18扩展会话Level1写 DID 最容易出的问题是长度不对。DID 配置多长你就必须写多长。7F 2E 13 长度错 7F 2E 31 DID 不支持写 7F 2E 33 没解锁第三组故障码 DTC0x19 ReadDTCInformation读故障信息19是 DTC 世界的入口。它不是只读一个东西而是一组动作读 DTC 数量 读 DTC 列表 读快照标识 读快照内容 读扩展数据 读所有支持的 DTC这个项目支持子功能用途01按状态掩码读取 DTC 数量02按状态掩码读取 DTC 列表03读取 DTC 快照标识04读取指定 DTC 快照内容06读取指定 DTC 扩展数据0A读取 ECU 支持的全部 DTC先理解一个关键字节statusOfDTC。本项目可用状态掩码是0x09也就是主要看bit值含义bit001testFailed当前测试失败bit308confirmedDTC已确认故障所以00 没有这些状态 01 当前失败 08 已确认 09 当前失败 已确认19 01读取 DTC 数量请求19 01 09意思是统计状态命中09的 DTC 有多少个。假设有 2 个正响应59 01 09 01 00 02解释字段含义5919 的正响应01回显子功能09ECU 支持的 DTC 状态位01DTC 格式ISO14229-100 02数量是 219 02读取 DTC 列表请求19 02 09假设当前命中两个 DTC59 02 09 90 80 16 09 C0 77 88 01从90 80 16 09开始每 4 字节一组DTC_H DTC_M DTC_L statusOfDTC所以字段含义90 80 16 09DTC 0x908016状态 09C0 77 88 01DTC 0xC07788状态 0119 03读取快照标识请求19 03它不是读快照内容只是问哪些 DTC 有快照快照记录号是多少例子59 03 90 80 16 01 90 80 16 02意思是DTC 0x908016 有 01 号快照 DTC 0x908016 有 02 号快照19 04读取指定 DTC 的快照内容请求读取0x908016的 01 号快照19 04 90 80 16 01这个项目快照里配置了 6 个 DIDDF01 DF02 DF03 DF04 DF05 DF06长度分别是DID长度DF013DF023DF036DF041DF051DF061正响应示例59 04 90 80 16 09 01 06 DF 01 12 34 56 DF 02 22 33 44 DF 03 01 02 03 04 05 06 DF 04 01 DF 05 02 DF 06 03拆开看字段含义5919 的正响应04回显子功能90 80 16DTC09statusOfDTC01快照记录号06后面有 6 个 DIDDF 01 12 34 56DF01 3 字节数据DF 02 22 33 44DF02 3 字节数据DF 03 01 02 03 04 05 06DF03 6 字节数据DF 04 01DF04 1 字节数据DF 05 02DF05 1 字节数据DF 06 03DF06 1 字节数据snapshotData就是快照记录号 DID 数量 多组 DID 编号 DID 数据当前代码允许快照记录号记录号含义01首次发生快照02最近一次快照FF读取该 DTC 下全部快照注意当前DF01到DF06的读取函数还是 TODO所以项目已经定义了快照结构和长度但还没实现这些 DID 具体代表什么业务信号。19 06读取指定 DTC 扩展数据请求19 06 90 80 16 01意思是读取 DTC0x908016的 01 号扩展数据记录。这个项目的 01 号扩展数据来自 EEPROM 镜像内容是字段含义fault_occur_op_cycles故障发生过的 operation cycle 次数dtc_aged_countDTC 因老化被清除的次数dtc_aging_count当前老化计数reserved两个预留字节代码固定填 0假设状态是09发生周期数是03老化清除次数是00当前老化计数是0559 06 90 80 16 09 01 03 00 05 00 00解释字段含义5919 的正响应06回显子功能90 80 16DTC09statusOfDTC01扩展数据记录号03fault_occur_op_cycles00dtc_aged_count05dtc_aging_count00 00预留当前工程19 06正常只支持扩展记录号01。DTC 不存在或者记录号不支持会回7F 19 3119 0A读取所有支持的 DTC请求19 0A它不是读“当前有故障的 DTC”而是读“这个 ECU 支持哪些 DTC”。正响应开头示例59 0A 09 90 80 16 09 90 80 17 00 C0 77 88 00 ...解释字段含义5919 的正响应0A回显子功能09DTCStatusAvailabilityMask90 80 16 09支持 DTC 0x908016当前状态 0990 80 17 00支持 DTC 0x908017当前状态 00C0 77 88 00支持 DTC 0xC07788当前状态 00这个项目一共配置了 102 个 DTC所以真实19 0A响应通常很长会走 ISO-TP 多帧。一句话区分子功能重点19 02按状态筛当前匹配的 DTC19 0A返回 ECU 支持的全部 DTC0x14 ClearDiagnosticInformation清故障码14服务就是告诉 ECU把某个 DTC 或某组 DTC 清掉。请求格式14 groupOfDTC_H groupOfDTC_M groupOfDTC_L清全部 DTC 常见请求14 FF FF FF正响应很短54如果清指定 DTC比如14 90 80 16意思是请求清 DTC0x908016。常见失败7F 14 13 长度错 7F 14 22 当前条件不允许清 7F 14 31 DTC 或分组不支持第四组控制 ECU 行为0x2F InputOutputControlByIdentifierIO 控制2F是很有现场感的服务。tester 不只是读数据而是临时接管某个输出。你可以把它理解成ECU先别按你自己的逻辑控制这个东西我临时给你一个控制值。请求格式2F DID_H DID_L controlParameter [controlState...]常见控制参数值含义00returnControlToECU交还 ECU 控制01resetToDefault恢复默认02freezeCurrentState冻结当前状态03shortTermAdjustment短期调节到指定值这个项目支持的 IO DIDDID对象控制值65015 通阀位置2 字节角度0 到 36065026 通阀位置2 字节角度0 到 3606503电机水泵byte0使能byte1速度 0 到 1006504空调水泵byte0使能byte1速度 0 到 1006505电池水泵byte0使能byte1速度 0 到 100示例控制电机水泵请求2F 65 03 03 01 50解释字节含义2FIO 控制65 03DID 0x6503电机水泵03shortTermAdjustment01使能50速度 0x50 80正响应6F 65 03 03 01 50它回显 DID、控制类型和控制值表示这次短期控制被接受。示例恢复空调水泵默认控制请求2F 65 04 01解释字段含义2FIO 控制65 04空调水泵01resetToDefault正响应6F 65 04 01常见失败7F 2F 13 长度错 7F 2F 22 当前条件不允许控制 7F 2F 31 DID、控制参数或控制值超范围 7F 2F 33 安全等级不够一句话记住2FDID 说明控制谁controlParameter 说明怎么控制后面的数据说明控制到什么值。0x28 CommunicationControl控制通信28服务不是控制某个水泵而是控制 ECU 的通信收发。常见子功能子功能含义00允许接收和发送01允许接收禁止发送03禁止接收和发送请求示例28 03 01解释字节含义28CommunicationControl03禁止 Rx 和 Tx01控制普通通信报文正响应68 030x85 ControlDTCSetting控制 DTC 是否更新85服务像是一个开关接下来 DTC 还要不要继续记录和更新常见子功能子功能含义01on开启 DTC 更新02off关闭 DTC 更新请求关闭 DTC 更新85 02正响应C5 02第五组例程和刷写0x31 RoutineControl执行内部例程31服务可以理解成ECU你执行一个内部动作。这个“内部动作”由 RID 表示。请求格式31 routineControlType RID_H RID_L [optionData...]常见子功能子功能含义01startRoutine02stopRoutine03requestRoutineResults这个项目常见 RIDRID含义0203检查编程前置条件FF00擦除内存0202校验内存FF01检查编程依赖示例检查编程前置条件请求31 01 02 03解释字段含义31RoutineControl01startRoutine02 03RID检查编程前置条件正响应71 01 02 03 00解释字段含义7131 的正响应01回显 startRoutine02 03回显 RID00routineStatus表示成功示例擦除内存请求31 01 FF 00 44 00 02 00 00 00 01 00 00拆开字段含义31RoutineControl01startRoutineFF 00擦除内存 RID44地址 4 字节大小 4 字节00 02 00 00起始地址00 01 00 00擦除大小擦除可能比较久所以 ECU 可能先回7F 31 78意思是请求收到了我还在处理。完成后再回71 01 FF 00 000x34 RequestDownload请求开始下载刷写流程里34是告诉 ECU我要往某个地址下载一段数据总大小是多少你能不能接请求格式34 dataFormatIdentifier addressAndLengthFormatIdentifier memoryAddress... memorySize...示例34 00 44 00 02 00 00 00 01 00 00解释字段含义34RequestDownload00不压缩、不加密44地址 4 字节大小 4 字节00 02 00 00下载地址00 01 00 00下载大小正响应74 20 01 02解释字段含义7434 的正响应20maxNumberOfBlockLength 占 2 字节01 02ECU 允许的最大块长度0x36 TransferData传输数据块34只是申请开始下载真正的数据靠36传。请求格式36 blockSequenceCounter transferData...示例36 01 AA BB CC DD解释字段含义36TransferData01第 1 块AA BB CC DD本块数据正响应76 01也就是回显已经接收的块序号。常见失败7F 36 24 没有先 34顺序错 7F 36 31 长度或范围不对 7F 36 72 写入失败 7F 36 73 块序号错 7F 36 92 电压过高 7F 36 93 电压过低0x37 RequestTransferExit结束下载所有数据块传完后用37收尾37正响应77它表示这次传输流程正常结束。如果还没传完或者流程状态不对就会出现7F 37 24第六组在线保持和复位0x3E TesterPresent我还在线诊断会话不是永久保持的。如果 tester 长时间不说话ECU 会因为 S3 超时回到默认会话。所以 tester 会周期性发3E 00ECU 回7E 00如果发3E 80通常表示抑制正响应tester 的意思是我还在线你知道就行不用回我。0x11 ECUReset请求复位11服务是让 ECU 复位。常见请求11 01意思是 hardReset。正响应51 01通常 ECU 会先发响应再执行复位。最后一段真正吸收 UDS 的口诀看 UDS 不要从“背服务码”开始要从“读一句话”开始。拿到一帧请求按这个顺序读1. SID这是什么服务 2. 子功能这次动作是什么 3. 对象操作哪个 DID、DTC、RID 或地址 4. 参数后面的值是控制值、写入值、状态掩码、记录号还是数据块 5. 条件它需要什么会话、安全等级、长度、前置条件 6. 正响应成功时回显什么又新增什么结果字段 7. 负响应失败是长度、条件、权限、范围还是顺序问题你把这个框架套到所有服务上UDS 就不再是一堆十六进制数字而是一套非常规整的问答协议。最后用一句话收住SID 说明我要干什么子功能说明具体动作DID/DTC/RID/地址说明操作对象后面的数据说明参数ECU 检查会话、安全、长度和条件成功回 SID0x40失败回 7FSIDNRC。