3. UDS服务分类:六大功能类别的实战解读
UDS诊断协议里,服务可不是随便排的。ISO 14229-1把它们分成了六大类。说实话,我刚接触这个分类时也觉得有点绕,但后来发现,这个分类其实非常符合实际开发场景。
你想想看,ECU开发过程中,你需要读数据、写数据、控制IO、运行程序、上传下载固件。这不正好对应了六大类吗?我个人习惯把这六类记成:诊通管、数传、存传、输控、例程、上传下。嗯,有点拗口,但好用。
3.1 诊断与通信管理类
这一类是UDS的"交通警察"。它负责管理诊断会话本身,而不是ECU的功能数据。
核心服务包括:
- 10 (DiagnosticSessionControl):切换诊断会话。默认会话、扩展会话、编程会话。我在项目中遇到过,有些ECU在默认会话下只响应部分服务,必须切到扩展会话才能做写入操作。
- 11 (ECUReset):复位ECU。硬件复位、钥匙下电复位、快速断电复位。我曾经踩过一个坑:复位后ECU没有及时发送应答,导致上位机超时报错。后来加了延时等待才解决。
- 27 (SecurityAccess):安全访问。说白了就是解锁。种子和密钥的算法要小心,我见过因为算法溢出导致解锁失败的案例。
- 28 (CommunicationControl):通信控制。可以关闭或开启某些报文。比如刷写时关掉应用报文,减少总线负载。
- 3E (TesterPresent):保持会话活跃。这个服务很简单,但忘了发的话,ECU会退出诊断会话。我刚开始做测试时经常忘,后来养成了定时发送的习惯。
- 83 (AccessTimingParameter):访问时序参数。调整通信超时时间,一般用得不多。
- 84 (SecuredDataTransmission):安全数据传输。用于需要加密的通信场景。
- 85 (ControlDTCSetting):控制DTC设置。可以关闭或开启故障码记录。调试时很有用。
实战要点:
诊断会话管理是基础中的基础。我建议你在实现时,先确保10服务和3E服务跑通。这两个不通,其他服务都白搭。
3.2 数据传输类
这一类是UDS里最常用的。说白了就是读数据、写数据。
核心服务:
- 22 (ReadDataByIdentifier):通过DID读取数据。比如读VIN码、读软件版本、读故障码状态。我习惯把DID按功能分组,比如0xF190是软件版本,0xF191是硬件版本。
- 23 (ReadMemoryByAddress):通过地址读取内存。这个服务比较底层,一般用于调试或刷写。
- 24 (ReadScalingDataByIdentifier):读取缩放数据。可以读到DID的转换公式和单位。
- 2A (ReadDataByPeriodicIdentifier):周期读取数据。ECU会按一定周期自动上报数据,减少总线请求次数。
- 2C (DynamicallyDefineDataIdentifier):动态定义DID。可以组合多个DID为一个新的DID,方便一次性读取。
- 2E (WriteDataByIdentifier):通过DID写入数据。比如写入VIN码、配置参数。注意:写入操作通常需要安全访问权限。
- 3D (WriteMemoryByAddress):通过地址写入内存。刷写时常用。
我的经验:
22服务和2E服务是开发中最频繁使用的。我建议你把DID做成表格管理,方便后续扩展。另外,写入操作一定要做边界检查,我曾经见过写入非法值导致ECU行为异常的案例。
3.3 存储数据传输类
这一类专门处理DTC(诊断故障码)相关的数据。嗯,就是故障码的读写和清除。
核心服务:
- 14 (ClearDiagnosticInformation):清除诊断信息。清除所有DTC或指定DTC。注意:清除后ECU会重新检测故障。
- 19 (ReadDTCInformation):读取DTC信息。这个服务子功能很多,比如读当前故障码、读历史故障码、读故障码快照等。我建议你重点掌握子功能0x02(按状态掩码读取DTC)和0x04(读取故障码快照)。
避坑指南:
我曾经遇到过一个问题:清除DTC后,ECU没有及时更新故障码状态,导致上位机读到旧的故障码。后来发现是清除操作后需要等待ECU重新检测。嗯,这个时序问题要注意。
3.4 输入输出控制类
这一类用于控制ECU的输入输出。说白了就是让ECU执行一些物理动作,比如控制继电器、驱动电机、读取传感器值。
核心服务:
- 2F (InputOutputControlByIdentifier):通过DID控制输入输出。可以强制输出为某个值,或者返回当前输入状态。我在项目中用这个服务来测试执行器,比如控制风扇转速、控制灯光开关。
实战要点:
2F服务很强大,但也很危险。你想想看,如果误操作控制了刹车或转向,后果很严重。所以我建议在生产环境中,2F服务必须加安全访问保护。我个人的习惯是:测试时用2F,量产时禁用。
3.5 例程功能类
这一类用于执行ECU内部的特定程序。比如自检、校准、复位某些模块。
核心服务:
- 31 (RoutineControl):例程控制。可以启动、停止、查询例程的执行结果。例程可以理解为ECU内部的一个函数,通过诊断请求来调用。
举个例子:我做过一个项目,ECU需要定期执行自检。我们通过31服务来触发自检,然后读取结果。这样上位机可以灵活控制自检时机。
我的建议:
31服务的例程ID要规划好。我习惯把例程ID按功能分组:0x0100-0x01FF是自检类,0x0200-0x02FF是校准类。这样方便管理和扩展。
3.6 上传下载类
这一类用于固件刷写和数据上传下载。说白了就是给ECU升级程序。
核心服务:
- 34 (RequestDownload):请求下载。告诉ECU我要下载数据了,ECU会返回允许的地址和大小。
- 35 (RequestUpload):请求上传。从ECU读取数据,比如读取日志文件。
- 36 (TransferData):传输数据。实际的数据传输服务,可以连续发送多个数据块。
- 37 (RequestTransferExit):请求传输退出。结束数据传输,ECU会做校验和完整性检查。
- 38 (RequestFileTransfer):请求文件传输。用于文件系统的操作,比如读写文件。
避坑指南:
刷写时最容易出问题。我曾经遇到过:传输过程中总线错误导致数据丢失,ECU刷成砖。后来我加了校验和重传机制。另外,刷写前一定要确保ECU处于编程会话,并且有足够的内存空间。
3.7 总结与对比
这六大类服务,各有各的用途。我整理了一个表格,方便你对比:
| 类别 | 核心服务 | 主要用途 | 我的建议 |
|---|---|---|---|
| 诊断与通信管理 | 10, 11, 27, 28, 3E, 83, 84, 85 | 会话管理、安全访问、通信控制 | 先跑通10和3E |
| 数据传输 | 22, 23, 24, 2A, 2C, 2E, 3D | 读写DID、读写内存 | DID做成表格管理 |
| 存储数据传输 | 14, 19 | 故障码读写清除 | 注意清除后的时序 |
| 输入输出控制 | 2F | 控制执行器、读取传感器 | 生产环境加安全访问 |
| 例程功能 | 31 | 执行内部程序 | 例程ID按功能分组 |
| 上传下载 | 34, 35, 36, 37, 38 | 固件刷写、文件传输 | 加校验和重传机制 |
嗯,这六大类就是UDS服务的全部家当了。你想想看,从诊断会话管理到固件刷写,UDS覆盖了ECU开发的整个生命周期。我个人觉得,掌握好这六类服务,你就能应对90%以上的诊断开发场景。
下一章,我们会深入讲解每个服务的具体实现。到时候我会结合代码示例,带你一步步实现这些服务。敬请期待。