详解汽车Bootloader设计

BootLoader(下文简称Boot)也称为引导程序,其主要用于软件更新。这就带来一个问题,ECU的软件更新方式有很多,比如通过JTAG调试更新软件,为什么要Boot呢?
由于ECU软件中难免会有BUG存在,以及要满足整车OTA需求,必须可以在不开盖的情况下更新软件。而ECU控制器对外的接口通常只有总线、电源和控制IO等。出于最大化复用接口(减少线束的重量和成本)考虑,通常采用基于UDS的Boot,而最常用的总线为CAN。为什么不用JTAG口呢?主要是ECU装车后,直接通过烧录器或者仿真器更新软件的很不方便,难以实现远程更新,另外由于JTAG口的权限很高,可以任意修改内部程序,安全风险很大。

01

BootLoader的设计需求

Boot除了正常满足更新软件需求外,还需满足以下需求。
1、安全需求
Boot和APP应该放在不同的内存区域,防止相互干扰。Boot中不应集成Flash Driver,避免程序在正常运行时非法修改FLash,导致软件异常,通常在刷写App或者标定数据时,先将Flash Driver下载至芯片的RAM中。
另外,在Boot执行App或者标定数据更新时,应该具有多重安全检查机制,确保刷入正确的软件。
首先在执行刷写流程之前,上位机对需要更新的软件包进行检查,通常包括两项,其一是在生成软件包时,开发人员会在特定位置增加一个与上位机约定的特定的ID,当上位机加载软件包时,会去检查软件包中存储的ID是否与上位机中相同,如果不同,则终止刷写,这样可以防止刷入其他ECU的软件包。
其二是在生成软件包时,会对特定地址区域进CRC计算,通常采用CRC32,并将该CRC值存储在特定的地址,通常是程序的末尾,在上位机加载软件包时,按照相同的CRC算法进行计算,并与软件包中存入的进行比较,如果相同则进行下面的流程。这也是俗称的完整性检查。
在以上确认软件包本身没有问题后,开始准备将软件刷入到车内的ECU中,在此之前需要对当前车辆的刷写条件进行检查,其中主要包括当前是否有车速,档位是否在P档,蓄电池电压是否过低,对于新能源车而言,还需检查高压继电器是否闭合等。如果有一个条件不满足,处于安全考虑,都会终止软件更新。
此后,在执行数据下载前,还需通过主机厂指定的0x27服务的安全算法,对数据下载命令进行解锁。
2、BootLoader自更新需求
对于刷写流程和刷写规范,主机厂通常有自己的一套,而在开发阶段,为了防止因早期boot中存在BUG而需要更新Boot,供应商通常会做Boot更新功能。
通常的做法是做两级Boot,分别为供应商自己的Boot和主机厂的Boot,具体如图1所示,其中SB为供应商自己的Boot,而CB为主机厂的Boot。除此之外还有其他很多方法,感兴趣的可以戳回送门—>如何实现BootLoader自更新呢?

图1 两级boot

3、更新速率需求

在当前主机厂都在追求整车OTA能力的情形下,主机厂开始在意软件的更新时间,尽量减少对用于的影响,也就是所谓的无感更新,提高用于体验,毕竟谁也不想出现几年前蔚来在长安街上等半天更新软件情形。

对此需要熟读芯片手册的Flash部分以及数据下载协议,多为UDS,目前通常采用的方法就是Flash执行多页写入,采取最大化的连续帧数量,也就是减少流控制的数量,亦或是提高总线速率等。

02

BootLoader程序流设计

ECU上电后,程序从链接文件中定义的RESET入口进入Boot,Boot在做完基本的初始化之后,会检查软件刷新标志位和App有效标志位,如果有效,则停留在Boot中等待执行软件刷写任务,如果无效,则跳转至App的入口地址,启动App。Boot的具体流程图如图2所示。
图2 Bootloader软件流程图
软件刷新标志位被置位通常有两种方式,其一为当App正常运行的时候,如果此时收到10 02切换至编程会话的命令,在App会将软件刷新标志位进行置位,通常写入至NVM,写入成功后,软件进行复位。这里涉及到NvM模块中的block在App和Boot中的同步管理。
其二是在Boot启动期间,收到10 02编程会话命令,Boot将软件刷新标志位进行置位,进入刷写流程。
在软件刷写流程中,通常分为个步骤,分别为预编程步骤、主编程阶段、后编程阶段。
1、预编程步骤

从名字可以看出,该步骤主要是下载程序前的一些操作,包括唤醒ECU、读写特定的DID、通信管理等,详细的操作如图3所示。

图3 预编程阶段

其中:

1、唤醒ECU,唤醒的方法和策略由主机厂制定,有些要求在KeyOn下刷写,有些要求在KeyOff下刷写。

2、为了运行85服务关闭DTC存储和28服务关闭相关的通信,首先需通过10服务切换至扩展会话,因为85和28服务都需要在扩展模式下才能工作。

3、进入扩展会话后,主机厂可以进一步进行特定数据链路的初始化,通常来说,国内主机厂不会有这种需求,不知道欧洲会不会有。

4、运行31服务对刷写条件进行检查,例如低压电是否在正常范围内,档位是否为P档,车速是否为零等;

5、检查通过后,为了防止刷写过程中其他ECU节点误触发DTC,通常为通信故障,则通过功能寻址请求85服务关闭局域网内所有ECU节点的DTC存储;

6、该步骤提供给主机厂一个接口,可以通过0x31服务启动或关闭ECU的故障安全响应(failsafe reaction),目前主机厂用得很少。

7、为了提高刷写速度,降低刷写程序时总线负载率,通过28服务关闭无关报文,比如应用报文和网络管理报文;

8、在关闭部分通信之后,通过22服务读取被刷ECU的状态(应用软件和数据)、软件指纹信息等;

9、为了减少刷写的时间,可以通过87服务提高CAN总线的波特率。

2、主编程阶段

该步骤用于将软件或者数据下载到被刷ECU中,主要包括进入特定的安全等级、写入指纹信息、下载软件和数据等,如图4所示。

图4 主编程阶段

其中:

1、10 02切换至编程会话模式,将软件刷新标志位置位,;

2、运行27服务进入特定的安全等级,下载前,通过安全访问过程是强制的,确保只有合法的诊断仪能对ECU进行下载操作。

3、运行2E服务将指纹信息写入ECU;

4、运行34、36、37服务将永久存储区写入默认值;

5、运行31服务检查步骤4是否成功,另外一种方法是通过37的响应确定是否成功;

6、运行31服务对特定的Flash进行擦除;

7、分别运行34、36、37服务将Flash driver下载至内存中;

8、运行31服务检查Flash driver下载是否成功;

9、分别运行34、36、37服务将软件包或者标定数据下载至Buffer中,Boot通过周期调用Flash Driver将数据写入Flash中;

10、运行31服务检查步骤9是否下载成功;

11、运行31服务验证程序是否能正常运行,例如checksum、标志位等;

12、在下载完软件和数据后,汽车制造产商需要一些特定的操作,比如写入VIN码等。

3、后编程阶段

该步骤主要通过11服务对ECU进行复位或者通过10服务将会话切换至默认会话,如图5所示,如果在预编程阶段中调整了波特率,须通过特定的操作将波特率调整至正常值。通常操作是运行11服务使ECU复位,重启ECU。

图5 后编程阶段


(0)

相关推荐