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%以上的诊断开发场景。

下一章,我们会深入讲解每个服务的具体实现。到时候我会结合代码示例,带你一步步实现这些服务。敬请期待。