3. 固件刷写基础

固件刷写(Firmware Flashing)是指将编译生成的固件镜像按照既定协议写入 ECU 非易失性存储器(如 Flash、EEPROM)的过程。它并不是简单的“拷贝文件”,而是一次受控的、可校验、可回滚的软件更新行为。理解刷写的本质,需要同时把握三个维度:写什么(镜像与地址布局)、怎么写(刷写方式与协议)、写坏了怎么办(校验与恢复)。

固件刷写 = 镜像传输 + 地址映射 + 擦除写入 + 完整性校验 + 激活生效。任何一环缺失,都可能导致 ECU 无法启动或功能异常。

一、刷写定义与核心原理

ECU 内部通常将存储器划分为多个区域:Bootloader 区、应用程序区(App)、标定数据区(Calibration)、配置参数区。刷写操作一般只针对应用程序区或标定区,而 Bootloader 区在正常刷写中保持只读,它是“最后一道防线”。

刷写的核心原理可以概括为“先擦后写、分块传输、逐块校验”。Flash 存储器的物理特性决定了写入前必须先擦除,且擦除以扇区(Sector)为单位。因此刷写工具需要根据目标芯片的扇区划分,将镜像切分为若干数据块,逐块下发。

典型刷写数据单元:
Sector 0 : 0x08000000 - 0x08003FFF  (Bootloader, 16KB)
Sector 1 : 0x08004000 - 0x08007FFF  (App 起始, 16KB)
Sector 2 : 0x08008000 - 0x0800BFFF  (App 续, 16KB)
...
刷写请求帧示例:
[0x02][0x34][0x00][0x44][0x00][0x00][0x80][0x00][CRC]
含义:RequestDownload,地址 0x08000000,长度 0x00008000

二、三种主流刷写方式对比

根据物理通道和触发主体的不同,固件刷写主要分为 OBD 刷写、Bootloader 刷写和 OTA 刷写。三者并非互斥,而是处于不同层级和场景。

刷写方式 物理通道 触发主体 典型场景 关键约束
OBD 刷写 OBD-II 诊断口 / CAN 诊断仪、产线设备 售后维修、产线下线 需进入诊断会话,依赖 UDS 服务
Bootloader 刷写 CAN / LIN / Ethernet 上位机刷写工具 ECU 开发、台架调试 需先跳转 Bootloader,有超时窗口
OTA 刷写 4G/5G / Wi-Fi / 以太网 车端 OTA 客户端 + 云端 远程升级、功能迭代 依赖网络、电量、安全认证

OBD 刷写是最传统的工程方式。诊断仪通过 OBD 口发送 UDS 诊断服务(如 0x10 进入编程会话、0x27 安全访问、0x34/0x36/0x37 传输数据),由 ECU 内的 Bootloader 或诊断栈接收并写入。它的优点是标准化程度高、工具链成熟;缺点是速率受 CAN 带宽限制,且必须物理接触车辆。

Bootloader 刷写更偏向底层。ECU 上电后先运行 Bootloader,若在约定时间内收到有效的刷写请求,则停留在 Bootloader 模式等待镜像;否则跳转到 App。这种方式常用于开发阶段,刷写速度快、可控性强,但需要开发者理解跳转地址、向量表重映射等细节。

OTA 刷写是当前智能网联汽车的主流趋势。云端将固件包下发到车端 OTA 客户端,客户端再通过车内网关转发给目标 ECU。OTA 刷写通常采用“A/B 分区”或“双备份”策略:新固件先写入备用分区,校验通过后再切换激活,失败可回滚。其核心挑战不在传输本身,而在于断电保护、版本一致性、签名验签和回滚策略。

ECU 固件刷写三种方式与流程概览 OBD 刷写 诊断仪 → OBD-II 口 → CAN UDS: 0x10 / 0x27 / 0x34 0x36 / 0x37 / 0x31 适用:售后、产线 速率:受 CAN 带宽限制 Bootloader 刷写 上位机 → CAN/LIN/ETH 上电跳转 Bootloader 等待刷写请求窗口 适用:开发、台架调试 速率:高,可控性强 OTA 刷写 云端 → 4G/5G/Wi-Fi → 车端 OTA 客户端 → 网关 → ECU A/B 分区 + 签名验签 适用:远程升级、迭代 关键:断电保护、回滚 通用刷写流程(以 UDS Bootloader 为例) ① 预编程 会话/安全访问 ② 擦除 RoutineControl ③ 传输 0x34/0x36/0x37 ④ 校验 CRC/签名 ⑤ 激活 复位/跳转 App 校验失败 / 断电 → 回滚至原固件或重试 刷写三要素:镜像正确、通道可靠、校验完整

三、刷写流程概述

无论采用哪种方式,一次完整的刷写都可以抽象为五个阶段:预编程、擦除、传输、校验、激活。

  1. 预编程:进入编程会话(0x10 0x02),执行安全访问(0x27),关闭非必要通信,确保刷写期间总线负载可控。
  2. 擦除:通过例程控制(0x31)或专用命令擦除目标扇区。擦除前必须确认地址范围,避免误擦 Bootloader。
  3. 传输:RequestDownload(0x34)协商块大小,TransferData(0x36)逐块下发,RequestTransferExit(0x37)结束传输。
  4. 校验:对写入区域计算 CRC32 或验签,与镜像清单中的值比对。校验不通过则拒绝激活。
  5. 激活:写入激活标志或复位 ECU,Bootloader 跳转到新 App。部分场景需要再次上电确认。
在工程实践中,建议将“校验”拆分为两级:传输过程中逐块校验(快速发现链路错误),传输结束后整体校验(确保镜像完整)。两级校验结合,可以显著降低刷写失败率。

四、典型场景与常见误区

场景一:产线 OBD 刷写。车辆下线时,诊断仪通过 OBD 口依次刷写多个 ECU。此时最怕的是刷写中断导致 ECU“变砖”。因此产线通常要求刷写电源稳定、刷写超时时间充足,并在刷写后执行功能自检。

场景二:OTA 远程升级。用户夜间停车后,车端 OTA 客户端从云端下载固件包,验签通过后写入备用分区。若升级过程中蓄电池电量低于阈值,OTA 客户端会暂停升级,避免断电导致写入失败。

常见误区:

  • 认为“刷写就是传文件”,忽略地址映射和扇区对齐,导致写入越界。
  • 忽略 Bootloader 与 App 的向量表偏移,跳转后中断无法响应。
  • OTA 只做传输校验,不做签名验签,存在被篡改固件注入的风险。
  • 刷写前未关闭看门狗或未处理超时,导致 ECU 在刷写中途复位。
刷写失败最常见的原因不是协议错误,而是电源异常、总线干扰和地址配置错误。工程上应优先保证供电稳定、线束可靠,再排查协议层问题。

总结来看,固件刷写是一项“协议 + 存储 + 安全 + 工程保障”的综合技术。OBD、Bootloader、OTA 三种方式分别对应不同的通道和场景,但底层都遵循“擦除—传输—校验—激活”的基本流程。掌握这一流程,是后续学习 UDS 刷写服务、Bootloader 设计和 OTA 安全机制的基础。