统一诊断服务简介

统一诊断服务,Unified diagnostic services(UDS)
UDS由ISO-14229系列标准定义,
ISO 14229-1定义了诊断服务,不涉及网络及实现,只有应用层的内容。
ISO 14229-3则定义了UDS在CAN总线上的实现。

诊断通信的过程就是诊断仪和ECU交换数据,诊断仪发送诊断请求(request),ECU给出诊断响应(response),而UDS最重要的作用就是定义了这些request和response的格式和内容。

Diagnostic request的格式:

Diagnostic request的格式可以分为两类:
一类是拥有sub-function的,
另一类是没有sub-function的,如下面两张图所示。

Service ID(以下简称SID)的长度固定为1个字节,代表了这条诊断命令执行的什么功能。sub-function的长度也是1个字节,它通常表示对这个诊断服务的具体操作,比如是启动、停止还是查询这个诊断服务。而后面的parameter则根据各个诊断服务的不同具有不同的内容,长度和格式并没有统一规格,它用于限定诊断服务执行的条件,比如某个诊断服务执行的时间等。parameter的一个重要应用是作为标识符,标识诊断请求要读出的数据内容,我会在后续的文章里详细讲述各个诊断服务的应用。

sub-function严格来说是7个bit,而不是1个byte,因为它的最高位bit被用于抑制正响应(suppress positive response,SPR),如果这个bit被置1,则ECU不会给出正响应(positive response); 如果这个bit被置0,则ECU会给出正响应。这样做的目的是可以告诉ECU不要发不必要的response,从而节约通信资源。

Diagnostic response的格式:

Diagnostic response分为positive和negative两类。

positive response意味着诊断仪发过来的诊断请求被执行了,而negative response则意味着ECU因为某种原因无法执行诊断仪发过来的诊断请求,而无法执行的原因则存在于negative response的报文中。

positive response的格式如上图所示,也基本上是由三部分组成,其中的response SID这个字节作为诊断请求的echo,它等于SID + 0X40。后面的两个部分则视具体的诊断服务而定。

negative response的格式固定为3个字节,第一个字节为0x7F,第二个字节是被拒绝掉的SID,第三个字节是这个诊断服务无法被执行的原因。下面这张图列举了部分原因代码,比如,如果ECU给出7F 22 13这个negative response,则说明22这个服务因为诊断请求数据长度不对的原因无法执行。

此处输入图片的描述

UDS定义的诊断服务从逻辑分类:

  • Diagnostic and Communication Management (诊断和通信管理)
  • Data Transmission (数据传输)
  • Stored Data Transmission (存储数据传输,用于操作DTC)
  • InputOutput Control (IO控制)
  • Routine Control (不知如何翻译好,作用是调用ECU内部的预置函数)
  • Upload Download (上传下载)

UDS规定使用1个byte来表示诊断服务,即所谓的Service ID,简称SID。

Diagnostic and Communication Management 类诊断服务

DiagnosticSessionControl (0x10)

DiagnosticSessionControl这个服务非常简单,但是它却是ECU和诊断通信的第一条诊断命令。服务的SID是0x10,request固定为2个byte,第、一个byte是SID,第二个byte的低7bit是sub-function,用于指示ECU将进入的session。UDS定义的session包括:

0x00 ISOSAEReserved(保留)
0x01 defaultSession
0x02 ProgrammingSession
0x03 extendedDiagnosticSession
0x04 safetySystemDiagnosticSession

0x05 – 0x3F ISOSAEReserved(保留)
0x40 – 0x5F vehicleManufacturerSpecific(由整车厂自定义使用)
0x60 – 0x7E systemSupplierSpecific(由ECU供应商自定义使用)
0x7F ISOSAEReserved(保留)

DiagnosticSessionControl用于控制ECU在不同的session之间进行转换,session可以看作是ECU所处的一种软件状态,在不同的session中诊断服务执行的权限不同。 ECU上电之后,默认处在defaultSession中,在这个session中很多诊断服务不可以执行,很多诊断相关的数据不能读取或写入。一般的诊断仪启动之后,会给ECU发送10 03,即让ECU进入 extendedDiagnosticSession中,在这个session中可执行的诊断服务就很多了。而如果要让ECU保持在non-defaultSession中,则需要诊断仪每隔固定的时间发送0x3E服务,ECU才会知道诊断仪有和自己通信的需求,从而保持在non-defaultSession中。

另一个常用的session是ProgrammingSession,在这个session中可以进行软件刷写的一系列诊断服务。0x40 – 0x5F 这个范围中的session由整车厂自定义使用,比如,某些诊断服务或诊断数据的操作需要在生产线上执行,即所谓的End-Of-Line,整车厂可以从这个范围中选择一个值来表示EOL session;又或者在开发阶段需要某种“超级”session,则也可以从这里选一个值用来使ECU进入开发模式的session。

这个诊断服务的response分为三部分,
第一部分是0x50,作为SID的echo;
第二部分是进入的session,作为sub-function的echo;
第三部分是4个字节,前两个字节代表P2Server_max,即ECU在应用层上对诊断命令的响应时间,后两个字节代表 P2 * Server_max,即ECU在暂时无法处理当前诊断命令(具体表现为发送了NRC 0X78),在应用层上对诊断命令响应的最长时间。

ECUReset (0x11)

ECUReset 这条指令的用途是通过诊断请求使ECU重启。

ECUReset 这个服务的SID是0x11,request固定为2个byte,第一个byte是SID,第二个byte的低7bit是sub-function,用于指示ECU将模拟哪种方式进行重启。

常用的sub-function包括

0x01 hardReset 模拟KL30的重启

0x02 keyOffOnReset 模拟KL15的重启

当我们通过诊断命令改写了ECU的某些数据,或者对ECU进行了某些设置,只有将ECU重启才能将这些配置生效,所以就有了这个诊断命令。在ECUReset 执行之后,ECU会从Non-defaultsession回退到defaultsession中。

SecurityAccess (0x27)

厂家可能会为ECU定义某些安全级别稍微高一些的诊断服务,在执行此类服务之前,就需要执行SecurityAccess 这个诊断命令,进行一个简单的身份验证。

完成SecurityAccess 有以下步骤:

1、诊断仪向ECU请求“Seed”(通常是一个与时间相关的伪随机数),
2、ECU向诊断仪发送“Seed”,
3、诊断仪向ECU发送“Key” (根据请求得到的Seed和一个本地的密码进行计算得来)
4、ECU判断诊断仪发来的“Key”是否有效

根据UDS的定义,
0x03, 0x05, 0x07 – 0x41 这个范围留给用于requestSeed的sub-function;
0x04, 0x06, 0x08 – 0x42这个范围留给用于sendKey的sub-function。

假设SecurityAccess的诊断命令中,0x05用于requestSeed,0x06用于sendKey, 。

诊断仪发送 27 05

ECU响应 67 05 01 01 01(seed是 01 01 01)

诊断仪发送 27 06 02 03 04(key值是02 03 04,seed是 01 01 01,假设本地密码为01 02 03,而算法就是将密码与seed相加)

ECU验证成功 67 06

此时ECU就处于unlocked的状态了,那些被保护起来的诊断服务和诊断数据可以被操作了。通常来说,如果ECU重启,或者回到了default session,unlocked状态就失效了,如果要执行相关诊断服务,则需要再次执行上面描述的过程。