转载来自:https://zhuanlan.zhihu.com/p/34886986 知乎张丁
这篇文章将介绍InputOutputControlByIdentifier (0x2F) 和RoutineControl (0x31) 这两个诊断服务的用途和用法。它俩的作用有点类似,都是调用ECU内部一些预定义的操作序列,相当于是我们从外部利用诊断手段控制ECU的接口。
InputOutputControlByIdentifier (0x2F)
ECU简单来说就是一个对输入(sensor)进行计算再产生输出(actuator)的系统。2F这个服务就是对ECU的输入和输出进行控制。这个服务在生产线上会需要使用,比如,在总装阶段,工人需要验证车上的各种功能是否正常,例如四个车窗的升降是否正常,如果挨个开关去按,那效率很低,如果通过一个诊断命令就能够观察到车窗升降的情况,效率则高得多。
ECU就是一个处理输入信息、输出控制的系统
比如,ECU接收一个输入信号A,我们就可以利用2F给这个A赋个我们需要的值;ECU对某个执行器B进行控制,我们就可以利用2F服务再配上某些特定的参数来实现对B的控制,例如门控对车窗升降、后视镜折叠等的控制。
2F命令的格式
2F服务的request由4部分组成
- SID
- dataIdentifier,用于标识被控制的IO对象
- controlOptionRecord,用于标识控制方式,比如是启动、停止控制,还可以有一些自定义的参数来进行更精准的控制,比如让某个执行器的动作持续多长时间。controlOptionRecord又分为两部分,分别是1个byte的inputOutputControlParameter,以及若干byte由厂家自定义使用的controlState。
- controlEnableMaskRecord,这是一个可选参数,用于标识controlOptionRecord中的哪些parameter被使用。
UDS明确定义了四种inputOutputControlParameter
0x00 returnControlToECU (将控制权还给ECU,即结束控制)
0x01 resetToDefault (将dataIdentifier所引用的输入信号、内部参数、输出信号等设为默认值)
0x02 freezeCurrentState(将dataIdentifier所引用的输入信号、内部参数、输出信号等冻结住)
0x03 shortTermAdjustment (将dataIdentifier所引用的输入信号、内部参数、输出信号进行设置,其实就相当于开始了对ECU的控制)
另外,UDS定义可以用22服务读取2F服务中使用的dataIdentifier,返回值是状态信息,具体的状态信息是什么,则由使用者自定义了。
我们以14229中举的一个例子来感受一下2F服务:
这个例子是使用2F控制Air Inlet Door Position (进气口门位置),用标识符0x9B00来标识进气口门的位置。Air Inlet Door Position [%] = decimal(Hex) * 1 [%] ,即用一个百分比来表示这个位置。
step1:
tester 发送22 9B 00读取当前进气口门的位置
ECU返回62 9B 00 0A , 0x0A = 10(dec),表示当前位置是10%
step2:
tester 发送2F 9B 00 03 3C ,表示要将进气口门的位置调整到60%,0x3C = 60(dec)
ECU返回6F 9B 00 03 0C,表示接受控制,当前进气口门的位置为12%。因为ECU收到请求后是立刻响应的,而门的位置调节需要时间,所以还没有达到60%。
step3:
过一段时间后tester 发送22 9B 00读取当前进气口门的位置
ECU返回62 9B 00 3C , 0x3C = 60(dec),表示当前位置已经到了60%
step4:
tester 发送2F 9B 00 00,将控制权交还给ECU
ECU返回6F 9B 00 00 3A,表示接受请求,当前位置为58%
step5:
tester 发送2F 9B 00 02,冻结9B 00这个ID所代表的进气口门位置这个状态
ECU返回6F 9B 00 02 32,表示接受请求,当前位置保持在50%
RoutineControl (0x31)
31服务是调用ECU内置的一些操作序列的接口,这个服务的应用很灵活,因为厂家可以根据自己的需要为ECU定义各种各样的内部操作,而要执行这些操作只需要调用31服务就好了。典型的用途包括检查边界条件、清除闪存、对数据进行较验、对软硬件依赖性进行校验等,甚至有需要的话可以进行恢复出厂设置的操作,还有很多与ECU自身逻辑功能相关的操作也可以定义。
31命令的格式2F命令的格式
31服务的request由4部分组成
- SID
- sub-function,用于标识要执行什么动作,启动(0x01)、停止(0x02)、查询结果(0x03)?
- routineIdentifier,用于标识要执行的routine
- routineControlOptionRecord,这是一个可选参数,用于标识routine执行时所需要的参数,由各家自定义它的内容
举个例子,假设用0x0809这个ID来代表检查ECU是否满足软件刷写条件(比如车速、转速为0,KL15接通等)的routine。
tester发送31 01 08 09来启动0x0809这个routine
如果所有条件都满足,则ECU返回71 01 08 09作为echo即可,如果条件不满足,则ECU返回7F 01 08 09 XX YY ZZ,后边的XX YY ZZ则表明哪些条件不满足,具体的内容就由厂家自己定义了。