编辑推荐: |
本文介绍了Bootloader相关内容。希望对您的学习有所帮助。
本文来自于微信公众号汽车嵌入式学堂,由火龙果软件Linda编辑、推荐。 |
|
Bootloader(以下简称 Boot)是所有支持在线重编程功能的
ECU 必备的软件模块。通常情况下,ECU 上电后直接启动并运行应用层软件(Application);但在满足特定条件时,例如接收到诊断会话控制请求(Service
0x10,子功能 0x02)或由于 Boot 跳转至应用失败,系统将停留或切换至 Boot 模式运行。
传统架构下,Boot 区域的软件一经烧录便不可更改,意味着其版本在整车出厂后无法通过远程方式更新,除非进行物理拆解。
然而,随着整车 OTA 要求的普及,越来越多的主机厂提出 Boot 也应支持自更新能力,以确保即便
Boot 本身发生潜在故障,也能通过刷写机制完成修复。此外,当前不少 ECU 开始采用 A/B 分区刷写策略(即双分区冗余机制),进一步增强系统在升级过程中的安全性与可靠性。
一、Boot的启动流程
ECU 上电后,系统首先进入 Bootloader(Boot)阶段。Boot 模块会执行一系列基础初始化操作,包括
CAN 驱动的初始化、I/O 模块配置等。初始化完成后,Boot 将检查刷新请求标志位(Flash
Request Flag)的状态。
若刷新请求标志位为有效(Valid),则 ECU 进入待刷写模式,等待外部刷写命令(如通过 UDS
协议)。
若刷新请求标志位无效(Invalid),Boot 将进一步检测应用程序(Application)的有效性。若应用程序有效,系统将从
Boot 跳转至应用程序区执行;若应用程序有效,系统将从 Boot 跳转至应用程序区执行;
当 ECU 正常运行于应用程序中,如收到编程会话请求(Service 0x10,Sub-function
0x02),应用程序会设置外部刷写请求标志位为有效,并触发一次 ECU 重启。重启后,Boot 按照上述逻辑再次判断刷新请求标志,从而进入刷写流程。

二、刷写流程
刷新时序分为三个编程步骤:
预刷新步骤:刷新前的CAN网络准备;
主刷新步骤:下载应用软件或应用数据;
后刷新步骤:重同步CAN网络。
1. 预刷新步骤

Step1:唤醒ECU,唤醒的方法和策略由汽车制造商制定;
Step2:为了关闭DTC存储和运行0x28服务关闭相关的通信,需运行0x10服务跳转至扩展会话;
Step3:进入扩展会话后,汽车制造商可以进一步进行特定数据链路的初始化;
Step4:运行0x31服务对刷写条件进行检查,例如低压电是否在正常范围内等。除了条件检查之外,还会有一些安全机制,保证刷写安全,避免以下几种情况:
a. 来自非法源的下载动作;
b. 当前刷新条件不满足;
c.下载错误的应用软件或应用数据到ECU;
d.软件之间不兼容,措施主要包括以下几种:
安全访问控制:为了防止未授权的刷写操作,ECU 通过诊断服务 0x27(Security Access)实现安全访问控制。该机制基于
SEED & KEY 流程,确保只有通过认证的诊断工具才能进入编程模式,从而保护系统免受恶意或错误编程的干扰。
刷写预条件校验:在执行刷写前,ECU 会对当前运行环境进行安全性判断。若存在以下任一异常情况:高压上电、低电压状态或车速不为零,系统将拒绝刷写请求,以防止刷写过程中发生潜在风险,确保
ECU 始终在安全状态下进行程序更新。
数据完整性校验:在刷写过程中,Bootloader 会对即将写入 Flash 的程序或数据执行完整性校验。每当一个逻辑模块下载完成后,Bootloader
使用 CRC32 算法对该模块的所有数据字节进行校验,确保数据传输与写入过程无误。此外,ECU 支持通过“检查编程完整性”例程(Routine
Control)触发完整性校验流程。当接收到该服务请求后,Bootloader 将计算目标区域的 CRC32
校验值,并与诊断仪请求中附带的参考校验值进行比对,以确认刷写数据的准确性与完整性。
软件一致性检查:为避免不兼容软件组合引发功能异常或严重系统故障,ECU 在刷写前会执行软件版本及数据一致性校验。这包括但不限于:应用程序与
Bootloader 的版本匹配校验、应用数据与应用程序的结构一致性验证等,确保整个系统在升级后的软件状态稳定可靠。
Step5:为了防止刷写过程中出现异常误触发DTC存储,运行0x85服务关闭DTC的存储。
Step6:该步骤提供给汽车制造商一个接口,可以通过0x31服务启动或关闭ECU的故障安全响应(failsafe
reaction);
Step7:为了提高刷写速度,降低刷写程序时总线负载率,通过运行0x28服务关闭无关报文,比如应用报文和网络管理报文;
Step8:在关闭部分通信之后,通过0x22服务读取被刷ECU的状态(应用软件和数据)、软件指纹信息等;
Step9:为了减少刷写的时间,可以通过0x87服务提高CAN总线的波特率。
2. 主刷新步骤
在完成预刷新步骤后,系统进入主刷新阶段。主刷新阶段对应单个 ECU 的刷写流程,因此所有诊断服务请求均采用物理寻址方式进行通信。

Step1:运行0x10服务进入programmingSession;
Step2:运行0x27服务进入特定的安全等级;
Step3:运行0x2E服务将指纹信息写入ECU;
Step4:运行0x34、0x36、0x37服务将永久存储区写入默认值;
Step5:运行0x31服务检查步骤4是否成功,另外一种方法是通过0x37的响应确定是否成功;
Step6:运行0x31服务对特定的Flash进行擦除;
Step7:分别运行0x34、0x36、0x37服务将Flash driver下载至内存中;
Step8:运行0x31服务检查Flash driver下载是否成功;
Step9:分别运行0x34、0x36、0x37服务将软件和数据下载至ECU的flash中;
Step10:运行0x31服务检查步骤9是否下载成功;
Step11:运行0x31服务验证程序是否能正常运行,例如checksum、标志位等;
Step12:在下载完软件和数据后,汽车制造产商需要一些特定的操作,比如写入VIN码等。
3. 后刷新步骤
该步骤主要通过诊断服务 0x11(ECU Reset)对 ECU 执行复位,或通过服务 0x10(Diagnostic
Session Control)切换至默认会话。正如图 3 所示,若在预编程阶段调整过通信波特率,则需通过特定操作将波特率恢复为正常值。通常的做法是发送
0x11 服务指令,使 ECU 完成复位,从而重新建立标准通信配置并返回正常工作状态。

三、刷写测试用例
在刷写功能开发完成后,需按照预先制定的测试用例对其进行系统性验证,以确保功能的正确性与稳定性。通常,刷写功能测试可划分为四大类。其中,第一类测试为模拟诊断仪执行正常刷写流程,测试内容涵盖了完整的标准刷写过程,包括应用程序与标定数据的刷写场景。相关测试用例如图所示,覆盖典型通信交互与关键路径验证,确保刷写功能在常规使用条件下运行正常。

接下来是错误注入测试,旨在验证系统在异常刷写条件下的鲁棒性与容错能力。测试的基本前提是:即使发生刷写中断、数据错误等非预期情况,系统的
Bootloader 仍应保持完好,且 DUT(被测设备)在重新上电后应能正常进入刷写流程,完成应用程序的重新下载与启动。该测试用例如图所示,主要覆盖通信中断、数据包错误、CRC
校验失败等典型异常场景,以确保 ECU 刷写机制具备足够的恢复能力与安全冗余。

随后进行刷写完整性测试,旨在验证刷写数据在传输与写入过程中的正确性与一致性。该阶段测试覆盖对刷写后程序区域的校验机制,例如通过校验和或
CRC 比较,确认所有逻辑块是否被完整且无误地下载至 Flash。典型测试用例如下图所示,重点验证
Bootloader 对数据完整性的检测能力,以及在发现错误时能否正确上报并中止启动过程。

最后是刷写流程及预条件相关测试,主要用于验证刷写服务在各种系统状态下的行为规范性与容错能力。测试重点包括:3E(Tester
Present)服务保持通信会话的有效性、刷写前的前置条件判断(如电压范围、车速、档位等),以及刷写过程中的异常处理机制(如刷写失败后的安全回退策略)。相关测试用例如下图所示,确保系统在复杂工况下仍能严格按照预期逻辑执行或拒绝刷写请求。

四、Boot自更新
Boot自更新的需求现在也是越来越多,主要为了修复Boot软件中存在的Bug。以下有几种Boot自更新的方案。
1. Supplier Boot(SB) + Customer Boot(CB)
通常情况下,供应商都有自己的平台软件,包括Boot和Appl。而各主机厂都有自己不同的软件升级规范,为了适配主机厂的需求,通常的做法是加一层Customer
Boot来实现客户的需求。那软件的运行顺序就是SB->CB->Appl,如图所示。这种做法可以简单、快速的满足CB也可以更新。

不过这种方式,通常情况下通过SB更新CB是通过供应商自己定义的升级流程,并且通过自己的上位机来实现升级。也就意味着这种方式只适应项目开发阶段,因为供应商的升级流程无法接入到整车的OTA流程。这种方式的优点就是简单,能很快地适配客户的需求,而且即使面向不同的客户,只需要简单的更改CB就可以满足需求,适应性比较好。但是缺点就是会浪费Flash空间。
2. 将Boot先放到RAM中运行,然后更新Boot的Flash区域
这种方式只需要一份Boot,其具体方案是,在Boot的链接文件中,将程序和数据映射到特性的RAM空间,然后在控制器上电时,首先将Boot的代码和数据搬运到RAM中,程序运行在RAM中,当收到更新Boot的需求时(这里需要上位机在发送更新指令的时候,区别是更新Boot还是App,比如通过在0x31服务写入不同的标志位进行区分),通过RAM中的程序以及上位机下载的Flash
Driver,将Boot的Flash区域进行更新。

这种方式的优点就是节省Flash空间,而且如果客户想把Boot自更新的功能保留到量产之后,也是可以的,因此控制器的升级是完全遵循主机厂的要求,不过这种方式有个缺点,就是在更新过程中,不能断电,一旦断电,控制器就会变成板砖,需要换件。另外程序运行在RAM中,对踩内存这种行为更加敏感。不过在整车上,出现意外断电的情况应该很少。首先升级之前会检查低压蓄电池的电压水平,甚至对新能源车来说,可以启动DCDC,来保证12V的稳定供应。
3. 两个CB+minBoot
这种方案下,有两个CB和一个miniBoot,miniBoot的作用很简单,就是根据引导区的标志位来决定切换到哪个Boot。其具体的运行方式是,当软件收到Boot更新指令时,软件复位,首先跳转到miniBoot,在miniBoot中,根据引导区标记(标记所需运行的Boot号,比如1代表Boot1,2代表Boot2)跳转到相应的Boot,假设当前运行是Boot1,在Boot1中根据刷新指令,将Boot2的Flash区域进行更新,更新完之后,将引导区标记写为2,然后软件复位,那么下次运行的时候就会切换到Boot2运行了。这种方案的优势就是可以保证刷新过程中断电不会导致控制器变成板砖,而且也可以在SOP之后继续使用。缺点也很明显,空间占用率比较大,软件复杂,需要三个Boot。

|