3、刷写流程设计:前置条件、主流程、后处理与失败策略
刷写流程设计,是整个测试环境搭建的核心骨架。说白了,就是你要让ECU按照你设计的剧本,一步步把固件写进去。我见过不少团队,上来就写测试脚本,结果刷到一半卡住了,查半天发现是前置条件没满足。嗯,今天我们就把这个流程拆开揉碎了讲清楚。
3.1 刷写前置条件
刷写不是插上诊断仪就能干的。你得先确认几个硬性条件。我个人习惯,在脚本里把这些检查项做成一个独立函数,每次刷写前自动跑一遍。
| 检查项 | 说明 | 检查方式 |
|---|---|---|
| 电压范围 | 通常要求12V±1V(乘用车) | 读取ECU供电电压 |
| CAN总线状态 | 总线不能过载,无持续错误帧 | 监听总线负载率 |
| ECU会话模式 | 必须处于扩展会话(0x03) | 发送10 03 |
| 安全访问解锁 | 刷写前必须解锁 | 发送27 01/02 |
| 刷写文件完整性 | HEX/S19文件校验和正确 | 本地CRC校验 |
我曾经遇到过一个问题:电压在刷写过程中突然掉到11V以下,结果ECU直接变砖。后来我强制要求每次刷写前先读电压,低于阈值直接报错退出。
3.2 刷写主流程
主流程其实就三个大阶段:预编程、编程、后编程。你想想看,这跟给手机刷机是一个道理——先备份数据,再写入系统,最后恢复设置。
3.2.1 预编程阶段
这个阶段的目标是让ECU进入可刷写状态。我一般按这个顺序来:
- 停止通信:发送28 03 00,让ECU停止发送应用报文,避免干扰刷写过程。
- 禁用DTC存储:发送85 02,告诉ECU别记录故障码了,刷写过程中出现临时错误很正常。
- 检查刷写依赖:有些ECU需要先刷写依赖模块,比如Bootloader版本检查。
我个人习惯在预编程阶段加一个超时控制。每个步骤等待响应不超过500ms,超时就重试一次。重试失败直接进入失败处理。
3.2.2 编程阶段
这是核心中的核心。UDS刷写用的是34/36/37服务,也就是请求下载、传输数据、请求退出传输。我画了一张流程图,你看一眼就明白了。
这里有个关键点:36服务的传输块大小。我记得有一次,我设了4KB的块大小,结果ECU响应时间越来越长,最后超时了。后来发现是ECU的接收缓冲区太小,改成2KB就正常了。所以,块大小不是越大越好,得看ECU的硬件能力。
3.2.3 后编程阶段
刷写完成不等于结束。后编程阶段要做三件事:
- 启用DTC存储:发送85 01,恢复故障码记录功能。
- 恢复通信:发送28 00 00,让ECU重新发送应用报文。
- 复位ECU:发送11 01,让ECU用新固件启动。
注意:复位后要等待ECU重新上线。我一般设置10秒超时,每500ms发送一次诊断请求,直到ECU响应为止。
3.3 刷写后处理
后处理不只是复位那么简单。我个人习惯在复位后做一次完整的功能验证:
- 读取ECU的软件版本号,确认刷写成功。
- 读取DTC状态,确保没有新增故障码。
- 执行几个关键功能测试,比如读取VIN、读取硬件版本。
你想想看,如果刷完发现版本号没变,那肯定是哪里出问题了。我遇到过这种情况,最后发现是刷写文件传错了,刷了个旧版本上去。
3.4 刷写失败处理策略
刷写失败是常态,不是异常。我总结了几种常见失败场景和应对策略:
| 失败场景 | 可能原因 | 处理策略 |
|---|---|---|
| 34服务拒绝 | 内存地址不合法、文件大小超限 | 检查刷写文件,重新请求 |
| 36服务超时 | 总线干扰、ECU处理慢 | 重传当前块,最多3次 |
| 37服务失败 | 数据校验错误 | 重新开始整个刷写流程 |
| 复位后无响应 | ECU变砖、Bootloader损坏 | 进入Bootloader模式重新刷写 |
| 版本号不匹配 | 刷写文件错误 | 检查文件,重新刷写 |
我曾经遇到一个棘手的问题:ECU在36服务传输过程中突然断电。恢复供电后,ECU既不能正常启动,也不响应诊断请求。最后只能用Bootloader模式强制刷写。所以,我建议在测试环境里加一个断电恢复测试用例。
3.5 刷写时间估算
时间估算,说白了就是算一笔账。我一般用这个公式:
总时间 = 前置条件检查时间 + 预编程时间 + 编程时间 + 后处理时间
编程时间 = (文件总大小 / 块大小) × (传输时间 + ECU处理时间)
举例:
文件大小:2MB = 2048KB
块大小:4KB
传输次数:2048 / 4 = 512次
每次传输时间:约10ms(CAN 500kbps)
ECU处理时间:约5ms
编程时间 = 512 × (10 + 5) = 7680ms ≈ 7.7秒
加上前置检查(2秒)+ 预编程(1秒)+ 后处理(3秒)
总时间 ≈ 13.7秒
当然,这只是理想情况。实际测试中,总线负载、ECU性能、重传次数都会影响时间。我建议在脚本里加一个时间统计功能,每次刷写都记录实际耗时,积累数据后就能估算得更准。
我个人习惯在测试报告里加上时间分布图。这样一眼就能看出哪个阶段最耗时,方便优化。