尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

UDS服务0x28(CommunicationControl)从报文结构到刷写排障实战

UDS服务0x28(CommunicationControl)从报文结构到刷写排障实战 这件事我印象特别深晚上十一点半产线返工工位传来消息某控制器刷写失败连续几台车报同样的问题。第一批排查的人以为是34/36/37传输数据环节出了问题通信参数改了好几轮问题依旧。我过去扫了一眼CANtrace发现整个刷写流程里压根没有0x28服务的身影——上一站EOL测试把通信状态禁掉了没有恢复ECU一直停在静默状态。这个折腾了测试团队大半夜的故障根子就出在CommunicationControl通信控制0x28服务的状态管理上。0x28是UDS协议里最容易被轻视、又最容易捅娄子的服务。很多新入行的同学知道它有四个控制模式但不知道它背后关联着会话模式、安全等级、整车状态、网络管理状态知道它是刷写流程的标配却不清楚选错communicationType会直接把ECU弄失联。这篇文章不打算把ISO 14229-1原文搬过来复述我想从诊断排查的角度把0x28的报文结构、NRC定位思路、刷写时序、脚本实现和现场坑位一次性讲清楚。适合刚接手UDS诊断开发的工程师也适合在产线被0x28困扰的测试同学。1. 一条指令控制整条总线0x28的报文结构与位定义1.1 三个字节讲清楚服务本质0x28服务的请求帧最短只有3个数据字节第一个是服务ID 0x28第二个是控制类型controlType第三个是通信类型communicationType。这里要注意一个容易混淆的点UDS标准里把第二个字节统称为Sub-function但0x28的Sub-function不是简单的序号它本质上是一个控制模式选择。为了把语义区分开ISO 14229-1把0x28的第二个字节定义成controlType取值如下controlType含义效果0x00enableRxAndTx使能接收使能发送恢复正常通信0x01enableRxAndDisableTx可以收、不能发0x02disableRxAndEnableTx不能收、可以发0x03disableRxAndTx收发全禁静默模式大部分实践中用到的是0x03和0x00刷写前用0x03把通信关掉结束后用0x00恢复。0x01和0x02相对少见但在很多智能传感器和控制器里是有意义的。举个例子某摄像头节点在做固件升级时期望它继续接收外部触发信号Rx保持使能但不要往外发图像数据Tx禁用这时候就用0x01而不是一刀切的0x03。另外第二个字节的最高位是suppressPosRspMsgIndicationBit。如果写成0x83含义就变成了“disableRxAndTx 抑制正响应”。这个位在生产节拍快的产线上很常用少一条响应就能省一点时间但对测试脚本而言就是个坑后面专门展开说。1.2 communicationType不是随便填的通信类型的位掩码第三个字节communicationType是按位掩码设计的每一位代表一类通信报文Bit位值通信类型bit00x01应用报文Applicationbit10x02网络管理报文Network Managementbit20x04诊断报文Diagnostic典型组合里0x03表示同时控制应用报文和网络管理报文这也是刷写流程里最常见的写法。0x01只控制应用报文0x02只控制网络管理报文。很多测试场景只需要控制应用报文就够了把NM留下来避免唤醒逻辑被误伤。注意两个坑。第一标准保留了bit3~bit7你把communicationType填成0x08或0x80绝大多数ECU会回NRC 0x31填0x00也一样等于没选择任何通信类型很多ECU也会拒绝。第二bit2是诊断报文逻辑上你可以用0x28去禁诊断报文的收发但实际项目中请尽量不要这么干。原因在第五章详聊先记住结论一旦禁了诊断报文的接收ECU很可能连0x28恢复命令都收不到了。1.3 从一段CANtrace看懂0x28的完整收发下面是我从实车上抓的一段典型请求物理寻址请求ID是0x7E0响应ID是0x7E8CAN ID 0x7E0 DATA: 03 28 03 03 CAN ID 0x7E8 DATA: 02 68 03第一行的0x03是ISO-TP单帧的PCI字节表示后面有3个有效字节。真正的UDS数据是28 03 0328是服务ID03是controlTypedisableRxAndTx03是communicationType应用报文网络管理报文。第二行响应里0x02同样表示后面有2个字节68是0x280x40的正响应回显03表示controlType原样返回。如果条件不满足你会看到类似这样的负响应CAN ID 0x7E0 DATA: 03 28 03 03 CAN ID 0x7E8 DATA: 03 7F 28 220x7F是负响应的固定服务ID0x28是被拒绝的服务0x22是NRC。这种格式在所有UDS服务里是一致的看到这一行就能直接定位是0x28被ECU拒绝了。这里我再强调一句0x28控制的是ECU对外通信的能力不是总线本身。你禁用某个ECU的应用报文发送物理总线上还是有其它的报文在跑被控制节点只是安静了。这个认知能帮你区分0x28和总线级测试工具别把问题想复杂。2. 0x28被NRC弹回来的排查链路从0x22到0x312.1 一次返工排查NRC 0x22背后的状态条件先讲一个我经历过的案例。某项目的车身控制器在做实车联调时测试同学往0x28发了disableRxAndTx结果ECU秒回NRC 0x22。测试同学第一反应是安全等级不够又去做27服务解锁结果解锁成功后再发0x28还是0x22。后来查诊断调查表才发现规范里写得很清楚0x28仅允许在车速信号无效或者车速小于5km/h的条件下使用。当时实车停在坡道上ESP报出的车轮速度刚好超过标定阈值ECU认为车辆还在滚动直接拒绝了通信关闭请求。这个案例很有代表性。0x28不是简单的外设开关它涉及到行驶安全。ECU设计者会给它加各种前置条件健康状态、挡位位置、充电状态、高压互锁、车速、甚至外部使能引脚的电平。一旦这些条件不满足就会返回NRC 0x22。所以排查0x28的NRC 0x22时首先要做的不是改代码而是把整车状态对齐到规范允许的边界内。2.2 高频NRC速查表与定位思路根据我这几年的经验0x28服务返回的NRC集中在下面几类NRC含义0x28场景下的典型原因排查方向0x12SubFunctionNotSupportedcontrolType填了0x04~0x7F或使用了保留的控制模式检查第二个字节0x13IncorrectMessageLengthOrInvalidFormat请求只有2个字节缺communicationType检查ISO-TP长度0x22ConditionsNotCorrect车速/挡位/充电等整车条件不满足或当前网络状态不允许读相关DID和状态位0x31RequestOutOfRangecommunicationType填0x00、0x08或保留bit被置位检查第三个字节的位掩码0x33SecurityAccessDenied部分ECU要求先27服务解锁才能动通信配置先做安全解锁0x7ESubFunctionNotSupportedInActiveSession该controlType在当前会话模式不被支持切换到扩展会话或编程会话需要特别注意的是不同ECU对同一个错误会返回不同NRC。有的ECU对错误的controlType返回0x12有的返回0x7E这是ISO 14229里子功能错误语义的历史遗留问题也和OEM的诊断规范有关。所以对照NRC排查时要结合该ECU的诊断调查表不能只看通用表。2.3 排查链路五步定位0x28问题把排查过程固化成一套动作能省很多时间。我的固定路线是先看trace里0x28请求有没有正确发到总线上PCI长度是否完整有没有被CAN控制器截断。看ECU有没有回响应回的是正响应还是负响应如果连负响应都没有说明ISO-TP或寻址就有问题。如果是负响应先定位NRC再打开诊断调查表看该NRC对应的前置条件。检查当前会话模式和安全等级必要时先执行10 03或10 02、27 01/02。用诊断仪或CANoe脚本模拟规范允许的状态把条件满足后再发0x28验证是否通过。这套链路在好几个项目里验证过90%的0x28异常都能在第3步和第4步里找到答案。3. 0x28在刷写流程里的位置通信关断的时序与恢复3.1 刷写前的通信关断时序刷写是0x28出场频率最高的地方。给ECU刷写固件的过程中如果应用报文还在正常周期发送可能干扰Bootloader对Flash的写入时序甚至触发应用层的看门狗复位。所以刷写流程的第一步不是马上写Flash而是先把ECU的正常通信停下来。一个典型的重编程时序是10 02切换会话到编程会话部分ECU是10 03。27 01 / 27 02完成安全解锁。28 03 03禁用应用报文和网络管理报文的收发。85 02关闭DTC记录可选视规范而定。19 02 / 14 FF FF FF读取或清除旧故障码。34 36 37请求下载、传输数据、退出传输。11 01复位ECU让App恢复运行。注意第3步里communicationType写的是0x03不是0x04。应用报文和NM都禁掉但诊断链路必须保留否则后面34 36 37一样都发不进去。另外第4步的85 02和0x28是两码事一个管DTC存储一个管通信收发别把它们混为一谈。不同ECU对第3步的容忍度差异很大。有的ECU在收到10 02编程会话切换后会自动进入低速响应模式即使不发0x28也能保证刷写安全有的ECU必须显式发0x28才能停掉NM。我建议在项目诊断规范里明确写上这一步不要靠ECU的自动行为兜底。3.2 不止刷写静默测试、NM抑制和EOL场景0x28的应用不局限于刷写。第一是静默测试。有些测试用例要求ECU在某个时间段完全不对外通信用来验证上位机或网关对节点失联的逻辑。这时候用0x28 03 03比直接拔插头正规得多也方便自动化回归。第二是网络管理抑制。需要模拟节点睡眠场景时可以对某个ECU发0x28 03 02只禁网络管理报文保留应用报文。这样应用层的收发还活着但网络管理器会认为节点离线从而触发睡眠或唤醒逻辑。第三是EOL下线检测。产线上经常不让ECU发正常报文但保留诊断能力方便产线设备做功能项测试这个场景下通常发0x28 03 01。还有一类场景容易被忽略网关型ECU。你对着中央网关发0x28 03 01网关可能会把下游子网的应用报文都停掉。这意味着0x28的影响范围不一定是单节点恢复的时候也要按相同路径逐个发恢复指令。3.3 通信控制的状态机什么时候会自动恢复很多工程师关心0x28设置后什么时候会恢复。从ISO 14229和多数OEM实现来看ECU复位0x11服务或下电重启后通信控制状态会恢复到默认的enableRxAndTx。也就是说0x28不是需要手动撤销的永久状态它更像一次性的控制指令掉电就失效。但有几个例外要留意。第一某些ECU在Bootloader里对0x28状态的恢复条件不一致App里设置的通信状态在进入Boot之后可能不生效。第二有些ECU会在0x28禁用通信期间记录一个“通信被外部强制关闭”的DTC或事件恢复通信后不会自动清除需要额外做清除故障码操作。第三部分网关型ECU会缓存通信控制状态直接对某一路发恢复指令还不够要按规范流程整体复位。这些行为差异在项目的诊断调查表里通常能找到线索。拿不到文档的项目我倾向于在ECU复位后主动发一条0x28 00 03做兜底恢复确保状态干净。4. 用脚本把0x28跑起来CAPL与Python两种落地方式4.1 CAPL里发一条0x28在CANoe环境里做诊断测试最省事的是在Diagnostic Console里用诊断描述文件直接发双击服务选择参数就行。但很多项目没有CDD或者测试节点是CAPL写死了的这时候就要在CAPL里手工构造请求。这里给一个基于CanTp的发送逻辑关键点是先拼出UDS数据段再调ISO-TP发送函数byte udsData[3] {0x28, 0x03, 0x03}; // SID0x28, controlType0x03, communicationType0x03 byte tpData[8]; // 封装ISO-TP单帧PCI0x03表示3字节数据 tpData[0] 0x03; tpData[1] udsData[0]; tpData[2] udsData[1]; tpData[3] udsData[2]; // 通过诊断物理寻址CAN ID发送 CanTpSendData(0x7E0, tpData, 4);如果你的工程里用的是ISO-TP DLL接口函数名可能是CanTp_Transmit或者diagSendRequest参数核心就两个目标CAN ID和数据指针。发送前记得把请求ID设置成物理寻址ID0x28不建议用功能寻址0x7DF因为一条功能寻址会同时控制总线上所有ECU容易把一整车节点弄静默。等待响应时可以用on diagResponse事件也可以在Test Module里用TestWaitForDiagResponse。对于0x28这种简单服务我一般设800ms超时。4.2 Python-can udsoncan快速验证如果不想开CANoe纯Python也能快速验证0x28。组合是python-can加udsoncan前者管CAN收发后者管UDS协议栈import can import udsoncan from udsoncan.client import Client from udsoncan.connections import PythonIsoTPSocketConnection # 建立ISO-TP连接物理寻址 conn PythonIsoTPSocketConnection(can0, rxid0x7e8, txid0x7e0) client Client(conn, request_timeout1) with client: resp client.change_communication_type( control_type0x03, # disableRxAndTx communication_type0x03 # 应用报文 网络管理报文 ) if resp.positive: print(0x28正响应) else: print(0x28负响应NRC: 0x%02x % resp.code)udsoncan把0x28封装成change_communication_type方法底层会自己组帧、分帧ISO-TP、解析正负响应。如果你的库版本比较旧没有这个方法也可以直接构造CommunicationControl服务实例或者自己组织裸字节发出去。需要注意PythonIsoTPSocketConnection要求CAN驱动和内核ISO-TP模块支持对应接口。插上USBCAN设备后先做回环测试确认链路通。我第一次用的时候在rxid和txid上写反了发了半天没响应检查驱动才发现把请求和响应ID搞混了。4.3 响应断言与超时设置的经验值0x28是一锤子买卖响应快正常都在100ms以内完成。我从实际项目里总结的经验是实车总线负载高的场景设1s超时台架直连ECU设500ms就够产线上如果开了suppress正响应位那就不是超时问题而是不能等响应。断言的时候不要只检查resp.positive还要检查回显的controlType。有些ECU会把0x83的suppress位原样回显有的会去掉高位只回0x03。如果脚本解析逻辑对这两种情况没有兼容处理看上去正响应了实际上你并不知道控制命令是不是按自己期望的那一个执行的。另外测试完记得主动恢复。自动化脚本里通常再加一条0x28 00 03并且等一小段时间通过观察ECU是否恢复发应用报文来确认恢复成功。5. 现场踩过的坑失联、BusOff与静默的正响应5.1 suppress正响应功能执行了但你在等一个不存在的回复前面提过0x83。有个真实案例某产线自动化脚本为了省时间在刷写前发了0x83 03脚本接着就等ECU的0x68响应超时后立刻报了刷写失败。返工查了一晚上排除了协议栈问题后才发现ECU其实已经静默了但正响应因为suppress位被压下去了。正确做法有两条要么不用suppress让ECU回正响应产线多等几十毫秒但结果明确要么用了suppress就要用别的信号验证。以刷写场景为例可以等ECU的NM报文停止或者读一个应用层心跳信号确认它已经不再发送。二者选其一别傻等着一条不会来的响应。5.2 communicationType0x04带来的失联我最想提醒的一个坑不要轻易往0x28的communicationType里填0x04。逻辑上标准允许但一旦把诊断报文的接收也禁掉ECU就再也听不到任何诊断请求了。你后面再想发0x28 00 03去恢复通信它根本收不到。有时候总线上其它ECU还会继续转发诊断报文现象更隐蔽。我见过一个项目测试同学想验证ECU的异常静默恢复机制用0x28 03 04把ECU彻底关静默了。结果ECU的协议栈直接把诊断报文也过滤掉恢复命令石沉大海最后只能整车下电重启。那次之后我在团队规范里加了一条0x28的communicationType禁止使用诊断位凡是需要静默诊断通道的场景一律走测试工具的总线干扰特性而不是走诊断服务。如果你实在要用0x04务必先实现一个可靠的恢复策略比如确认该ECU在下一次启动周期会恢复enableRxAndTx或者有独立的看门狗复位引脚否则一旦失联只能拔电。5.3 禁了NM之后CANoe里的节点红了用CANoe做网络管理仿真时经常遇到这种情况对被测ECU发了0x28 03 03接着CANoe的NM窗口里该节点状态就变成BusOff、睡眠或者超时。很多同学以为是0x28把CAN控制器搞挂掉了其实ECU只是按指令停止了NM报文的发送。这种场景下的恢复顺序很重要。先发0x28 00 03恢复通信然后在CANoe的NM状态机里手动触发一次唤醒或者等网络管理状态自动回归节点状态就会重新变成Active。不要去重启CANoe也不要急着重新上电先确认诊断链路还在不在链路在就一定能救回来。另外如果被测ECU的下游还有子节点0x28禁了主节点的NM子节点因为接收不到主节点的NM报文也可能进入睡眠。这种级联影响在台架测试中尤其常见排查时要往外多看一眼。5.4 我自己用的一份0x28自查清单把这些坑都经历一遍之后我给自己写了一份固定动作每次发0x28之前先过一遍确认当前会话模式支持0x28一般需要扩展会话或编程会话。确认安全等级已解锁按ECU规范要求执行27服务。确认communicationType里没有置诊断位通常用0x03或按规范限定。实车条件下确认车速、挡位、充电等状态满足规范要求。确认用的是物理寻址不是功能寻址。确认脚本有没有依赖正响应以及suppress位有没有被误置。测试收尾主动发0x28 00 03并观察ECU应用报文是否恢复。这七条看着简单但每一次出问题基本都能落回到其中某一条。写到这里关于0x28该讲的都差不多了。最后分享一点个人习惯我现在做UDS诊断测试凡是遇到0x28相关的诡异现象第一反应不是去看应用层代码而是先抓一段10分钟的trace看CAN ID、PCI、NRC三件套。协议栈层面的东西往往就藏在这三样里。0x28作为通信控制服务本身不复杂复杂的是它和会话、安全、整车状态、网络管理之间的联动。把这些联动关系理清楚你就能在排查这类问题时少走很多弯路。
返回列表