TC3xx AB-Bank FBL 刷写流程
2026/8/21 19:48:05 网站建设 项目流程

车载ECU Flash Bootloader(FBL)通用流程与Flash Driver详解

本文从行业通用视角出发,基于ISO 14229(UDS)诊断标准与AUTOSAR规范,梳理车载ECU中Flash Bootloader(FBL)的完整工作机制,重点讲清Flash Driver的概念与作用、AB/Bank分区升级、安全校验、上电启动跳转等核心知识点。不绑定特定芯片或项目,适合面试准备与技术入门。


一、FBL是什么?行业定位

FBL(Flash Bootloader)是ECU Flash中一段独立、受写保护的引导程序,专门负责通过诊断接口对ECU应用程序(APP)进行刷写升级。

它在整车软件架构中的位置:

┌─────────────────────────────────────┐ │ APP(应用层,整车业务逻辑) │ ├─────────────────────────────────────┤ │ FBL(Flash Bootloader,刷写程序) │ ├─────────────────────────────────────┤ │ 芯片ROM Boot(出厂固化,不可改) │ └─────────────────────────────────────┘

核心职责(行业通用):

  • 接收UDS诊断命令,完成固件下载、擦除、编程
  • 对新固件做完整性校验与签名验签
  • 管理分区切换(A/B Bank)与回滚
  • 上电时判断启动哪个分区,完成跳转到APP

FBL本身一般不允许被正常诊断流程刷写,防止升级过程中掉电导致Bootloader本身损坏、ECU变砖。


二、Flash Driver:概念与作用(重点)

2.1 什么是Flash Driver?

Flash Driver(Flash驱动程序)是直接操作MCU内部Flash控制器硬件寄存器,完成Flash**擦除(Erase)、编程(Write/Program)、读取(Read)**的底层驱动模块。

在AUTOSAR架构中,它属于MCAL层的Fls模块,向上提供标准化的擦写接口,向下直接操作Flash控制器寄存器。

应用层 / FBL ↓ 调用擦除/编程接口 Flash Driver(Fls模块,MCAL层) ↓ 操作寄存器 Flash控制器硬件 → Flash存储阵列

2.2 为什么FBL需要单独关注Flash Driver?

这是车载Bootloader领域的一个核心技术点,原因有二:

原因1:擦写Flash时,Flash本身不可读

很多MCU的Flash控制器在执行擦除或编程操作期间,整个Flash阵列处于Busy状态,CPU无法从Flash取指。如果FBL本身存放在Flash里,而擦写代码也在Flash里,就会出现"自己擦自己正在运行的代码"的问题——CPU取指失败,程序跑飞。

解决方案:把Flash Driver拷贝到RAM中运行。FBL在需要擦写Flash前,将Flash Driver的代码段复制到RAM,然后从RAM调用擦写函数。此时即使Flash处于Busy状态,CPU从RAM取指不受影响。

原因2:不同MCU的Flash控制器差异极大

英飞凌AURIX、NXP S32、瑞萨RH850、TI TMS570等,各家Flash控制器的寄存器布局、擦写时序、保护机制完全不同。为了让FBL主体逻辑(UDS协议、状态机、校验)保持通用,通常把芯片相关的Flash操作封装成独立的Flash Driver,FBL只调用标准接口。

2.3 两种实现方式(行业通用)

方式说明适用场景
FBL内置Flash DriverFlash Driver代码直接编译进FBL镜像,存放在Flash;运行时FBL将其拷贝到RAM执行简单MCU,Flash控制器不复杂,Driver体积小
诊断下载RAM版Flash DriverFBL本身不带Flash Driver,升级时通过UDS的34/36/37将一个独立的Flash Driver下载到RAM,校验后从RAM调用复杂MCU(如AURIX、S32),Driver体积大、芯片差异大,便于单独维护和升级

第二种方式是高端MCU的主流做法:FBL只负责UDS协议和流程控制,真正的Flash擦写动作由下载到RAM的Flash Driver完成。这样FBL可以适配同系列不同Flash容量的芯片,而不需要重新编译FBL。

2.4 RAM版Flash Driver的下载与调用流程

① FBL通过UDS 34/36/37将Flash Driver下载到RAM ② 对RAM中的Flash Driver做签名验签(防止恶意驱动) ③ 验签通过 → FBL标记"Flash Driver就绪" ④ FBL调用RAM中的Flash Driver接口,执行Flash擦除/编程 ⑤ 刷写完成后,RAM中的Driver随掉电消失(不持久化)

关键点:Flash Driver下载到RAM后,必须做签名验签。因为它运行在特权级别,直接操作硬件,如果被篡改,后果比APP被篡改更严重。


三、典型Flash分区布局

车载ECU普遍采用**A/B双分区(Dual Bank)**架构,这是行业通用的安全升级方案:

┌──────────────────────────────┐ │ FBL区(Bootloader,写保护) │ ├──────────────────────────────┤ │ 元数据区(Metadata/Header) │ │ - A/B分区Valid标记 │ │ - 活跃分区标记 │ │ - 固件版本、CRC、签名信息 │ ├──────────────────────────────┤ │ APP-A分区(当前运行固件) │ ├──────────────────────────────┤ │ APP-B分区(影子/备份分区) │ └──────────────────────────────┘

A/B分区升级核心思想:

  • 升级时只刷写非活跃分区(比如当前跑A,就刷B),活跃分区不动
  • 新固件校验通过后,修改元数据区的活跃分区标记
  • 下次上电从新分区启动
  • 如果新固件启动失败,可回滚到旧分区,永远不会变砖

部分MCU硬件支持Bank交换(Bank Swap),通过寄存器直接切换两个Bank的地址映射,不需要软件做地址偏移;不支持硬件Bank交换的,则由FBL软件做地址重映射。


四、完整UDS刷写时序(ISO 14229标准)

以下是行业通用的UDS在线刷写流程,所有车载ECU基本都遵循这套服务序列:

┌──────────────────────────────────────────────────────┐ │ 10 02 进入编程会话(Programming Session) │ │ ↓ APP应答后做安全关闭,软复位进入FBL │ │ 27 安全访问(Security Access)解锁 │ │ ↓ 未解锁禁止擦写Flash │ │ 31 01 FF00 例程控制:擦除目标分区 │ │ ↓ 只擦非活跃分区,活跃分区不动 │ │ 34 请求下载(RequestDownload) │ │ ↓ 指定目标地址(RAM或Flash)、数据长度 │ │ 36循环 传输数据(TransferData),分块传输固件 │ │ ↓ FBL接收数据,调用Flash Driver写入Flash │ │ 37 退出传输(RequestTransferExit) │ │ ↓ 通知FBL数据传输完毕 │ │ 31 01 0202 例程控制:执行固件校验(完整性+验签) │ │ ↓ 校验通过 → 写Valid标记、切换活跃分区 │ │ 11 ECU复位(Reset) │ │ ↓ 重启后FBL从新分区启动APP │ └──────────────────────────────────────────────────────┘

如果采用"RAM版Flash Driver"方案,在擦除/编程之前,会先用同样的34/36/37流程把Flash Driver下载到RAM并验签,然后才开始下载APP固件。


五、安全校验机制:完整性校验 + 签名验签

刷写完成后,FBL必须对新固件做安全校验,这是防止刷写传输错误和恶意固件注入的关键环节。行业通用做法是双层校验

5.1 第一层:完整性校验(Integrity Check)

目的:检测固件在传输、存储过程中是否发生比特错误、数据损坏。

常用算法:CRC32、SHA-256。

通用实现方式

  • 编译阶段,PC工具对固件计算CRC/SHA摘要,将摘要嵌入固件包的固定位置(元数据区或固件末尾)
  • 刷写时摘要随固件一起写入Flash
  • 校验时,FBL有两种做法:
    • 方式A(标准):FBL读取Flash中整片固件,现场重新计算CRC/SHA,与元数据区存的摘要比对
    • 方式B(简化):FBL不重算,直接将诊断报文携带的摘要副本与Flash中预存的摘要做内存比对

方式A更安全(能检测Flash固件本身是否被篡改),方式B执行更快但安全性弱,仅能检测传输错误。量产项目推荐方式A。

5.2 第二层:数字签名验签(Signature Verification)

目的:确认固件来自合法发布方(OEM/Tier1),防止恶意篡改、中间人攻击。

通用算法:RSA-PSS、ECDSA。基于非对称密码体系。

PC端(私钥,严格保密): 固件 → 计算SHA-256哈希 → 用私钥对哈希做签名 → 签名块 ECU端(公钥,烧录在FBL/HSM中): 读取Flash固件 → 计算SHA-256哈希 → 用公钥验签 → 比对哈希是否一致

关键点

  • 私钥只在OEM/Tier1的安全编译环境中存在,绝不下发到ECU
  • 公钥烧录在ECU的FBL或HSM(硬件安全模块)中,受写保护
  • 验签通过 = 固件确实是持有私钥的一方签发的,且未被篡改

5.3 两层校验的关系

校验层检测什么防不住什么
完整性校验(CRC/SHA)传输错误、Flash损坏、随机比特翻转恶意篡改(攻击者可同步修改摘要)
签名验签(RSA/ECDSA)恶意篡改、伪造固件、中间人攻击

只有两层校验全部通过,FBL才会将新分区标记为Valid(合法可启动)。任意一层失败,新分区保持Invalid状态,上电不会从该分区启动。

部分安全要求高的项目(如功能安全ISO 26262 ASIL-D、信息安全ISO 21434),还会使用HSM硬件加速验签,并在每次上电启动时对APP做一次启动校验(Secure Boot)。


六、上电启动全流程:BootROM → FBL → APP

每次ECU上电或复位,启动链路分为三段,这是所有车载MCU的通用架构:

6.1 第一段:芯片ROM Boot(出厂固化)

芯片上电后,CPU从固定的ROM地址开始执行。这段代码由芯片厂商出厂固化,用户不可修改

ROM Boot干的事:

  1. 芯片最底层初始化:PLL时钟、看门狗、RAM控制器
  2. 读取Flash中的启动模式头(Boot Header/BMHD),校验其校验和
  3. 从启动头中取出用户Bootloader(FBL)的入口地址
  4. 跳转到FBL

如果启动头校验失败(Flash空白、数据损坏),ROM Boot会进入芯片内置的串行下载模式(BootROM模式),等待通过UART/CAN下载,这是芯片级的最后恢复手段。

6.2 第二段:FBL(用户Bootloader)

FBL拿到控制权后,不会立刻跳APP,而是执行一套启动决策流程:

步骤1:基础初始化

  • 系统时钟、RAM、Flash控制器、CAN控制器初始化
  • 全局变量、状态机初始化
  • 关闭可能残留的中断

步骤2:判断是否进入刷写模式

满足以下任一条件,FBL留在刷写模式,不跳APP

  • 诊断仪请求了编程会话(CAN上有合法的10 02帧)
  • 硬件强制升级引脚被激活(产线工装)
  • A/B两个分区均无Valid标记(没有可启动的APP)

步骤3:读取元数据区,选择启动分区

FBL读取元数据区,根据Valid标记和活跃分区标记决策:

A区ValidB区Valid决策
合法不合法启动A
不合法合法启动B
都合法启动活跃分区标记指向的分区
都不合法留在FBL等刷写

步骤4:对选中分区做启动前校验(Secure Boot)

  • 检查分区向量表是否合法(非全0xFF,说明Flash未被擦空)
  • 对APP分区做CRC/SHA校验(安全等级高的项目每次上电都验)
  • 检查签名是否有效(部分项目只在刷写时验,上电只验CRC)

步骤5:跳转前的清场工作

跳转APP前必须完成:

  • 关闭FBL使能的所有外设中断,清除挂起的中断标志
  • 关闭FBL打开但APP不需要的外设
  • 设置栈指针(SP)为APP的栈顶地址(从APP向量表第一个字取出)
  • 切换中断向量表基地址(FBL和APP的向量表在不同Flash地址,必须切换,否则APP中断会跑到FBL的ISR)
  • 重新配置内存保护单元(MPU)为APP的内存布局

步骤6:执行跳转

// 通用伪代码 uint32_t app_sp = *(volatile uint32_t*)APP_BASE_ADDR; // 向量表第1字:栈顶 uint32_t app_pc = *(volatile uint32_t*)(APP_BASE_ADDR + 4); // 向量表第2字:复位入口 __set_stack_pointer(app_sp); // 切栈 ((void (*)(void))app_pc)(); // 跳转到APP复位处理函数

6.3 第三段:APP(应用程序)

APP的复位处理函数执行:

  1. C运行环境初始化:.data段从Flash拷贝到RAM,.bss段清零
  2. 系统初始化:时钟、外设、RTOS、通信栈
  3. 进入main(),执行业务逻辑
  4. 运行中收到10 02编程会话 → APP做安全关闭 → 软复位 → 重新回到ROM Boot → FBL检测到编程请求,进入刷写模式

6.4 启动链路总览

上电/复位 │ ▼ ROM Boot(芯片固化) ├─ 初始化时钟/看门狗/RAM ├─ 校验启动头(Boot Header) └─ 跳转到FBL入口 │ ▼ FBL(用户Bootloader) ├─ 初始化硬件 ├─ 是否需要刷写?→ 是则留在FBL ├─ 读元数据,选A/B分区 ├─ 启动校验(CRC/签名) ├─ 清中断、切栈、切向量表 └─ 跳转到APP │ ▼ APP(应用程序) ├─ .data/.bss初始化 ├─ 系统/外设/RTOS初始化 └─ main() 业务运行

七、面试速记版

  1. FBL:独立受保护的刷写程序,升级时运行,APP此时已停止。
  2. Flash Driver:操作Flash控制器完成擦写的底层驱动;因擦写时Flash不可读,需拷贝到RAM运行;复杂MCU通过UDS下载RAM版Driver。
  3. A/B分区:升级只刷非活跃分区,校验通过后切换活跃标记,断电/失败可回滚,不变砖。
  4. UDS刷写序列:10 02 → 27 → 31擦除 → 34 → 36循环 → 37 → 31校验 → 11复位。
  5. 双层校验:完整性(CRC/SHA,防传输错误)+ 签名验签(RSA-PSS/ECDSA,防恶意篡改),都通过才标记Valid。
  6. 私钥/公钥:私钥在OEM端签发固件,公钥在ECU端验签,私钥绝不下发。
  7. 上电三段式:ROM Boot(校验启动头→找FBL)→ FBL(选分区→校验→清场→跳APP)→ APP(初始化→main)。
  8. 跳转关键动作:切栈指针、切中断向量表基址、清中断,三者缺一不可。

APP flash 布局图

Block 地址范围 大小 归属 ───── ────────────────── ────── ────────────────────────────── 0~12 0x80000000~0x80033FFF 208KB Bootloader 代码区(TriCore) 13 0x80034000~0x80037FFF 16KB A区有效标志扇区 14 0x80038000~0x8003BFFF 16KB A区RSA签名扇区 15 0x8003C000~0x8003FFFF 16KB A区CMAC扇区 16~31 0x80040000~0x8007FFFF 256KB HSM固件区(ARM Cortex-M) ───── ────────────────── ────── ────────────────────────────── 32~63 0x80080000~0x800FFFFF 512KB A区APP第一段(运行区) 64~79 0x80100000~0x8013FFFF 256KB A区APP第二段 ── A区总计 768KB,当前APP只用前576KB(到0x8010FFFF) ── ───── ────────────────── ────── ────────────────────────────── 80~109 0x80140000~0x801B7FFF 480KB B区APP第一段(备份/下载区) 110~124 0x801B8000~0x801F3FFF 240KB B区APP第二段 125 0x801F4000~0x801F7FFF 16KB B区RSA签名扇区 126 0x801F8000~0x801FBFFF 16KB B区CMAC扇区 127 0x801FC000~0x801FFFFF 16KB B区有效标志扇区 ── B区总计 752KB(Block80~126) + 16KB标志(Block127) ──

product flash 布局图

0x80000000 ┌──────────────────────────────────┐ │ Bootloader 启动向量+中断表 │ 256B 0x80000100 ├──────────────────────────────────┤ │ Bootloader 代码主体 │ ~113KB │ (诊断/CAN/Flash驱动/安全校验/ │ │ AB分区/HSM交互) │ 0x8001C034 ├──────────────────────────────────┤ │ 保留(全0xFF) │ ~96KB 0x80033FFF ├──────────────────────────────────┤ │ 保留(全0xFF) │ 32B 0x80034020 ├──────────────────────────────────┤ │ APP有效标志 0xAA55AA55 │ 4B ← 仅PRODUCT 0x80034024 ├──────────────────────────────────┤ │ 保留(全0xFF) │ ~16KB 0x80037FFF ├──────────────────────────────────┤ 0x80038000 │ APP RSA-4096 PSS 签名 │ 512B 0x80038200 ├──────────────────────────────────┤ │ 保留(全0xFF) │ ~16KB 0x8003BFFF ├──────────────────────────────────┤ 0x8003C000 │ APP AES-CMAC │ 16B 0x8003C010 ├──────────────────────────────────┤ │ 保留(全0xFF) │ ~16KB 0x8003FFFF ├──────────────────────────────────┤ 0x80040000 │ HSM固件(ARM Cortex-M) │ ← 仅PRODUCT │ ├ 向量表(MSP+Reset+IRQ) │ │ ├ 代码主体(.text) │ ~116KB │ └ 数据/常量池 │ 0x8005D002 ├──────────────────────────────────┤ │ 保留(全0xFF) │ ~140KB 0x8007FFFF ├──────────────────────────────────┤ 0x80080000 │ APP程序 │ │ ├ 自定义头(32B:向量/长度/后门) │ │ ├ 中断向量表 │ 576KB │ ├ 代码主体(.text) │ │ ├ 常量(.rodata) │ │ └ .data初始化值+0填充 │ 0x8010FFFF └──────────────────────────────────┘ 0xAF400000 ┌──────────────────────────────────┐ │ UCB BMHD0 (启动模式头) │ 512B ← 仅PRODUCT 0xAF400200 ├──────────────────────────────────┤ │ 保留 │ 0xAF401000 ├──────────────────────────────────┤ │ UCB BMHD1 (冗余备份) │ 512B ← 仅PRODUCT 0xAF401200 ├──────────────────────────────────┤ │ 保留 │ 0xAF402400 ├──────────────────────────────────┤ │ UCB HSM配置块1 │ 2KB ← 仅PRODUCT 0xAF402C00 ├──────────────────────────────────┤ │ 保留 │ 0xAF403400 ├──────────────────────────────────┤ │ UCB HSM配置块2 │ 2KB ← 仅PRODUCT 0xAF403C00 └──────────────────────────────────┘

写在最后

车载FBL的技术核心可以概括为四句话:

  • Flash Driver在RAM运行,解决"擦写Flash时Flash不可读"的硬件约束
  • A/B双分区,实现不掉砖的安全升级与回滚
  • 完整性+签名双层校验,兼顾传输可靠性与信息安全
  • ROM Boot → FBL → APP三段式启动,保证从复位到业务运行的整条链路可控

理解了这四点,无论是面试还是实际项目,都能建立起完整的知识框架。安全等级高的项目还会叠加HSM硬件安全模块、Secure Boot上电验签、功能安全监控等机制,这些都是在上述基础架构上的延伸。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询