1 前言
这一章来说说ISO14229-1(UDS服务),在上一章介绍了ISO15765,提到了ISO15765-3中规定的UDS服务其实就是照搬的ISO14229-1,所谓UDS服务理解也是非常简单,就是两个角色进行数据交互,这两个角色分别是客户端和服务端,客户端首先向服务端发送服务请求,然后服务端根据服务类型进行回应。这里的客户端一般为诊断仪,而服务端则是车中的ECU模块了。
在这里不妨简单介绍一下ISO14229,ISO14229其实才是最完整的UDS协议规范,它不仅定义了UDS服务端,而且还定义了UDS在不同的硬件总线上的定义和要求,比如CAN,Ethernet,LIN等。ISO14229每个部分的内容如下所示:
UDS定义了几大类服务,分别是诊断和通信管理功能,数据传输功能,存储数据传输功能,输入输出控制功能,例行程序功能,上传下载功能,如下表所示:
2 服务数据格式
上面罗列了所有的诊断服务,种类很多,但是它们在数据组织上都遵循了一定的格式,这个格式理解起来很简单,前面多次提到了UDS其实是一种客户端请求,服务端响应的一种交互模式,这个请求和响应的格式是有一个定式,其中唯一的一个区别就是有无子功能,在服务表标明了每一个服务是否具有子功能。
2.1 无子功能的格式
请求的格式如下:
0 | 1 ~ n |
---|---|
服务ID | 用户自定义数据 |
响应分为正响应和负响应两种,所谓正响应就是指服务端认为请求有效,回复正确响应,而负响应则是指服务端认为该响应无效,有问题,则返回错误代码。
正响应格式如下:
0 | 1 ~ n |
---|---|
服务ID + 0x40 | 用户自定义数据 |
负响应格式如下:
0 | 1 | 2 |
---|---|---|
7F | 服务ID | NRC(错误码) |
举个简单的没有子功能的请求响应例子,客户端想用22服务(ReadDataByIdentifier)向服务端请求读取地址0xF187的DID数据,其请求和响应如下:
请 求:22 F1 87
正响应:62 F1 87 xx xx xx xx
负响应:7F 22 7E
2.2 有子功能的格式
请求的格式如下:
0 | 1 | 2 ~ n |
---|---|---|
服务ID | 子功能ID | 用户自定义数据 |
正响应格式如下:
0 | 1 | 2 ~ n |
---|---|---|
服务ID + 0x40 | 子功能ID | 用户自定义数据 |
负响应格式如下:
0 | 1 | 2 |
---|---|---|
7F | 服务ID | NRC(错误码) |
举个简单的带有子功能的请求响应例子,客户端想用10服务(DiagnosticSessionControl)向服务端请求切换会话模式,其请求和响应如下:
请 求:10 01
正响应:50 01 xx xx xx xx
负响应:7F 10 7E
下面列出一些常见的NRC码:
3 物理寻址和功能寻址
CAN总线上可挂载多个节点,当一个节点发送数据时,总线上所有的节点都会接收到消息,所以就需要通讯地址区分每个节点。大家都知道CAN ID可以作为地址信息进行寻址,而UDS在CAN ID的基础又提出了物理寻址和功能寻址两种寻址方式,物理寻址指的是请求端与单个响应端之间的通信,而功能寻址是请求段与多个响应端之间的通信。即请求端通过物理寻址方式发送请求时,只能有一个ECU可以回复响应;如果通过功能寻址方式发送请求时,同一网络中支持该功能寻址的所有ECU都需要回复响应。
举个简单的例子:整车同一网络中有多个ECU节点,分别为A, B, C, D,假设他们的物理请求地址为0x701, 0x702, 0x703, 0x704,响应消息地址分别为0x70A, 0x70B, 0x70C, 0x70D,所有ECU的功能寻址ID为0x7DF,现在将诊断仪接上网络,发送诊断请求报文:
物理寻址时:
0x701 0x10 0x01 (对ECU A进行诊断请求)
0x70A 0x50 0x01 xx xx xx xx (仅ECU A响应)
功能寻址时:
0x7DF 0x10 0x01 (对所有ECU进行诊断请求)
0x70A 0x50 0x01 xx xx xx xx (ECU A响应)
0x70B 0x50 0x01 xx xx xx xx (ECU B响应)
0x70C 0x50 0x01 xx xx xx xx (ECU C响应)
0x70D 0x50 0x01 xx xx xx xx (ECU D响应)
4 服务简介
下面对一些常见的服务的用法,格式,正响应进行简单介绍,具体请参考ISO14229-1。在这里也推荐一个专栏《ISO 14229》- 作者: 菜鸡小詹,在这个专栏里对很多常用的服务都作了详细的介绍,大家也可以参考这个专栏。
在介绍过程出现的的表格出现的Cvt项目含义为:
Cvt | 描述 |
---|---|
M | 强制的,不可选择 |
S | 强制的,只能从规定列表中选择 |
U | 非强制,用户自定义,可选择 |
4.1 诊断会话控制(0x10)
会话模式有默认会话模式(default session)和非默认会话模式(non-default session),非默认会话模式包含编程会话模式(ProgrammingSession)、拓展诊断会话模式(extendedDiagnosticSession)及其余会话模式。会话模式可以理解为诊断的功能模式,很多服务在默认会话模式下不支持的,所以在进行某些服务请求之前需要发送DiagnosticSessionControl会话控制服务请求将会话模式切换成非默认会话模式。不同的会话模式支持哪些服务请参考ISO14229-1。
10服务数据格式:
这里的sub-function分为多种,最常用的有01-defaultSession,02-ProgrammingSession,03-extendedDiagnosticSession三种。下图显示了这三种模式的切换图:
10 03 |
10 02 |
10 01/Reset |
10 01/Reset |
defaultSession
extendedDiagnosticSession
ProgrammingSession
ECU在刚上电或者复位之后处于默认会话模式(0x01),默认会话模式下发送10 03可以切换至拓展会话模式(0x03),拓展会话模式发送10 02可以切换至编程会话模式(0x02),而在默认会话模式不可以直接切换至编程会话模式。
10服务的正响应格式:
CAN报文示例:
1.请求报文中,02表示单帧2个字节,10为服务ID 0x10,03为切换为拓展会话模式。
2.响应报文中,06表示单帧6个字节,50为服务ID 0x10+0x40,03为子功能,00 32 13 88为应用层超时参数P2。
4.2 ECU复位(0x11)
ECU复位ECUReset(0x11)是控制ECU端执行复位的服务。诊断仪发送11 01复位请求后,ECU复位动作执行前,正响应需先发送给诊断仪,然后ECU执行复位操作,成功复位后,ECU需进入默认会话模式。
11服务数据格式:
这里的sub-function分为多种,常用的有01-hardReset,02-keyOffOnReset,03-softReset等等,在这里就不多说了,感兴趣的小伙伴可以参考ISO14229-1。
11服务的正响应格式:
CAN报文示例:
1.请求报文中,02表示单帧2个字节,11为服务ID 0x11,01为子功能hardReset。
2.响应报文中,02表示单帧2个字节,51为服务ID 0x11+0x40,01为子功能hardReset。
4.3 安全访问(0x27)
安全访问SecurityAccess(0x27),简单的来说为一些特别的服务提供一个简单的安全模式,而这些服务通常与ECU设备安全息息相关,比如写DID数据服务(0x2E)。也就是说要想进行这些特别服务请求之前,需要使用安全访问服务(0x27)进行进入安全验证,只有验证通过才能正常进行这些特别服务请求。
安全验证的流程如下图所示:
Client Server 发送seed请求 发送seed 发送Key 接收key 验证通过后 激活安全模式 发送验证响应 Client Server
客户端发送seed请求数据格式:
服务端发出seed响应格式:
客户端发送Key数据格式:
服务端发出验证响应格式:
其中seed请求中的子功能值为奇数,对应的key请求验证的子功能值为该奇数加1,如27 01与27 02为一组安全等级,27 03与27 04为一组安全等级,27 11与27 12为一组安全等级。不同的安全等级由客户定义功能区分。
CAN报文示例:
1.seed请求:02为单帧2个字节,27为服务ID 0x27,01为seed请求
2.seed响应:06为单帧6个字节,67为服务ID 0x27+0x40, 01为seed请求,12 34 56 78为seed。
3.Key发送:06为单帧6个字节,27为服务ID 0x27,02为key发送,13 35 57 79为Key。
4.Key响应:02为单帧2个字节,67为服务ID 0x27+0x40, 02为key响应。
4.4 读DID数据(0x22)
读DID数据ReadDataByIdentifier(0x22)用于从ECU存储器中读取固定DID所指定的数据记录值,DID说白了就是一个变相的虚拟地址,其中DID为两个字节长度的数值。
22服务数据格式:
22服务的正响应格式:
CAN报文示例1,单帧情况,DID的数据长度为3:
1.请求报文中,03表示单帧3个字节,22为服务ID 0x22,F1 8B为DID。
2.响应报文中,06表示单帧6个字节,62为服务ID 0x22+0x40,01 02 03为数据。
CAN报文示例2,多帧情况,DID的数据长度为7:
1.请求报文中,03表示单帧3个字节,22为服务ID 0x22,F1 8A为DID。
2.响应报文中,10 0A表示首帧,共10个字节数据,62为服务ID 0x22+0x40,F1 8A为DID,01 02 03为前三个字节数据。
3.客户端接收到首帧后,发送流控帧,30为流控帧CTS,00为BS,0F为STmin。
4.服务端接收到流控帧后,继续以连续帧的形式发送剩余数据,21为连续帧第一帧,04 05 05 07为剩余数据。
4.5 写DID数据(0x2E)
写DID数据WriteDataByIdentifier(0x2E)就是根据DID写入数据服务,允许诊断仪将数据写入由DID指定的内部存储单元,ECU应在数据写入成功后发送该服务的肯定响应,该服务需要在非默认会话模式下才能进行服务请求。
2E服务数据格式:
2E服务的正响应格式:
CAN报文示例1,单帧情况,DID的数据长度为3:
1.客户端发送10服务请求切换至扩展会话模式
2.服务端响应成功切换
3.请求报文中,06为单帧6个字节,2E为服务ID 0x2E,F1 8B为DID,01 02 03为要写入的数据。
4.响应报文中,03为单帧3个字节,6E为服务ID 0x2E+0x40,F1 8B为DID。
CAN报文示例2,多帧情况,DID的数据长度为7:
1.客户端发送10服务请求切换至扩展会话模式
2.服务端响应成功切换
3.客户端发送2E服务请求,10 0A表示首帧,共10个字节数据,2E为服务ID 0x2E,F1 8B为DID,01 02 03为部分要写入的数据。
4.服务端接收到首帧后发送流控帧,30为流控帧CTS,00为BS,0F为STmin。
5.客户端使用连续帧继续发送剩下数据,21为流控帧第一帧,04 05 06 07为剩余数据。
6.服务端发送成功响应,03为单帧3个字节,6E为服务ID 0x2E+0x40,F1 8B为DID。
4.6 读取故障码(0x19)
读故障码信息ReadDTCInformation(0x19)就是去读取ECU内部DTC数据。DTC管理在ECU中其实也算是一个蛮复杂的模块,所以DTC数据也是蛮复杂的(这里就不多做赘述了,后面有机会会专门整个文章来介绍了DTC,感兴趣的小伙伴也可以参考ISO14229-1),这就导致了19服务的子功能特别多,而且每种子功能后所跟着的参数内容也是大有不同,而其正响应内容也不同,在这里就举其中一个子功能为reportSupportedDTC(0x0A)例子,19 0A请求格式如下:
其正响应如下:
CAN报文示例:
4.7 清除故障码(0x14)
清除故障码ClearDiagnosticInformation(0x14)就是用来清除ECU存储的所有DTC信息,其请求格式如下:
上表中出现一个参数为groupOfDTC,这个意思其实DTC里面的一个小概念,就是DTC会把一些故障按照种类进行分类,一类就叫做一个group,所以可以附加这个参数按组来删除DTC信息,如果这个参数为0xFFFFFF,那么就是清除所以DTC信息。
正响应格式如下:
CAN报文示例:
4.8 例程控制(0x31)
例程控制RoutineControl(0x31)其实就是相当于一个外部程序控制器,比方说ECU内部有个测试程序,那么就可以通过例程控制服务来对这个内部测试程序进行控制,控制其运行,停止,获取程序运行结果。
31服务请求格式:
31服务正响应格式:
上表中的子功能即routineControlType最常见的为01-startRoutine,02-stopRoutine。03-requestRoutineResults,而参数routineIdentifier则是例程ID,就是通过这个ID来区分不同的例程,至于routineControlOptionRecord则是可选择的附加参数,由用户自行定义。
CAN报文示例:
就列举这些常见的服务了,其他的服务可以参考ISO15765手册。
4.9 控制输入输出(0x2F)
控制输入输出InputOutputControlByIdentifier(0x2F)的功能跟31服务有点类似,31服务一般用来控制内部程序,而2F服务则是一般用来接管ECU的输入输出的控制权,这些输入输出一般有LED,开关阀门这些等。该服务在默认会话模式下是不支持的,需要先切换会话模式才能进行服务请求。
2F服务请求格式:
2F服务正响应格式:
上表中的dataIdentifier为输入输出ID,就是通过这个ID来区分不同的输入输出,在controlOptionRecord参数中的inputOutputControlParameter为操作类型,主要有00-returnControlToECU,01-resetToDefault,02-freezeCurrentState,03-shortTermAdjustment。
CAN报文示例: