详解汽车Bootloader设计
BootLoader(下文简称Boot)也称为引导程序,其主要用于软件更新。这就带来一个问题,ECU的软件更新方式有很多,比如通过JTAG调试更新软件,为什么要Boot呢?
由于ECU软件中难免会有BUG存在,以及要满足整车OTA需求,必须可以在不开盖的情况下更新软件。而ECU控制器对外的接口通常只有总线、电源和控制IO等。出于最大化复用接口(减少线束的重量和成本)考虑,通常采用基于UDS的Boot,而最常用的总线为CAN。为什么不用JTAG 口呢?主要是ECU装车后,直接通过烧录器或者仿真器更新软件的很不方便,难以实现远程更新,另外由于JTAG口的权限很高,可以任意修改内部程序,安全风险很大。
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执行多页写入,采取最大化的连续帧数量,也就是减少流控制的数量,亦或是提高总线速率等。
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服务都需要在扩展模式下才能工作。