BootLoad(简称Boot)是一种启动加载程序,或者称为引导程序,我们在操作系统和嵌入式开发中经常用到,因为汽车ECU也是一种嵌入式系统,Boot程序主要用于ECU软件更新,汽车OTA升级,本文主要讲述汽车bootloader程序的工作原理和设计方法。
BootLoader,通常是驻留在ECU非易失性存储器(NVM,None Valitale Momory)中的一段程序加载代码,每次ECU复位后,都会运行bootloader。它会检查是否有来自通信总线的远程程序加载请求,如果有,则进入bootloader模式,建立与程序下载端(通常为PC上位机)的总线通信并接收通信总线下载的应用程序、解析其地址和数据代码,运行NVM驱动程序,将其编程到NVM中,并校验其完整性,从而完成应用程序更新。如果没有来自通信总线的远程程序加载请求,则直接跳转到应用程序复位入口函数(复位中断ISR,也称作Entry_Point()–使用Processor Expert的CodeWarrior 工程或者Startup()函数–普通CodeWarrior 工程),运行应用程序。
与远程程序下载端建立可靠的总线通信以获取要更新应用程序;
解析应用程序编程文件(S19/HEX/BIN)获得其在NVM中的地址和程序代码及数据;
运行NVM驱动将应用程序的代码和数据编程到NVM中并校验;
MCU片内集成的用于存放数据的EEPROM或者Data-Flash;
用于存储程序代码/数据的Code-Flash/Program-Flash;
MPU扩展的片外NORFlash或者NAND-Flash;
对NVM的擦除(erase)、编程(program)和校验(verify)等基本操作;
对NVM的加密(secure)/解密(unsecure)和加保护(protecTIon)/解保护(unprotecTIon)操作。
MCU片上集成的NVM中EEPROM/D-Flash和C_Flash/P-Flash一般属于不同的block,所以可以直接在Flash上运行NVM驱动对EEPROM/D-Flash进行擦除和编程操作;
NVM驱动一般都是通过运行一个NVM command序列,在其中通过NVM控制器寄存器给出不同的NVM操作命令代码、NVM编程数据和目标地址的方式完成,典型的NVM command序列有(Freescale的S12(X)系列MCU Flash write command 序列);
由于NVM的工作速度一般较CPU内核频率和总线频率低,所以运行NVM驱动前必须对NVM进行初始化,将设置分频器其工作频率设置为正常工作所需频率范围;
MCU片内的NVM同一个block上不能运行NVM的驱动对其自身进行擦除和编程操作,否则会传出read while write的总线访问冲突(每个NVM block只有一条数据总线,一个时刻只能进行读出或者写入,不支持同时读出和写入)。因此对于仅有一个block Flash的MCU来说,就必须在RAM中调用其NVM驱动,来对其自身进行擦除和编程操作,同时在launch Flash command到等待command完成期间必须关闭CPU全局中断,禁止外设中断响应,否则取中断向量和运行中断ISR都会访问Flash。要使能中断,就必须将中断向量表偏移到RAM或者NVM block(EEPROM/D-Flash)并将响应的中断ISR也拷贝到其他RAM或者NVM block上(当然该中断向量表也必须更新指导新的中断ISR);
由于以上2的要求,通常需要将bootloader的NVM驱动拷贝到MCU的RAM中运行,其可以将其完成的NVM拷贝到RAM中运行,也可以只拷贝NVM command launch到等待command完成的几条指令到RAM执行即可,因为NVM驱动中其他操作(比如填写NVM操作命令、写入编程地址和数据等)并不会往占用数据总线上往NVM中写入数据;
NVM的驱动程序驻留在Flash中,如果出现堆栈溢出等意外程序跑飞意外运行NVM驱动程序则会造成NVM内容意外擦除丢失或者修改的情况。因此需要对关键数据或代码(比如bootloader本身)进行保护以防止意外修改,或者更为安全的方法是**不将NVM驱动程序存放在NVM中,而是在bootloader最开始通过上位机将其下载到RAM中运行,bootloader结束后将该区域RAM清除,**从而避免由于意外运行NVM驱动程序造成的NVM数据丢失和修改。
一般MCU厂商都会给出其MCU的NVM驱动库,用户可以使用该类库实现NVM操作,如果是Freescale/NXP的汽车级MCU,还可以使用CodeWarrior IDE集成的Processor Expert生成相应的NVM驱动程序;
1. bootloader与应用程序的关系:
bootloader和应用程序分别是两个完整的MCU软件工程,各自都由自己的启动代码、main()函数、链接文件、外设驱动程序和中断向量表;
因此bootloader和应用程序的链接文件中,对NVM的地址空间分配必须分开独立,不能重叠(overlap),但其RAM分配没有约束,两者都可以使用整个RAM空间,因为跳转到应用工程后,将启动代码将重新初始化RAM;
bootloader必须使用MCU默认的中断向量表,因为每次复位后MCU都是从其默认中断向量表的复位向量取地址执行的;应用程序的中断向量必须进行偏移(通过相应的中断向量偏移寄存器,如S12(X)系列MCU的IVBR寄存器或者ARM Cortex M系列MCU的SCB-》VTOR寄存器);而NVM(P-Flash)的擦除都是按照sector进行的,所以为了充分利用NVM(P-Flash)空间,都将bootloader分区到包含默认中断向量表的若干NVM(P-Flash)sector(S12(X)系列MCU的NVM最后若干sector, ARM Cortex M系列MCU从0地址开始的若干sector);
跳转时机:方法有:1)bootloader更新完应用程序并校验其完整性OK之后,将用到的外设(比如CAN/LIN通信总线模块、定时器、GPIO等)寄存器恢复到复位后的默认状态,然后直接跳转;bootloader更新完应用程序并校验其完整性OK之后,等待看门狗定时器超时溢出复位,在bootloader最开始判断无远程应用程序下载请求而跳转;推荐使用方法2):因为方法1)相对于软件复位,其跳转至应用程序复位启动函数时MCU的硬件环境与直接运行应用程序可能存在差异,而方法2)的看门狗复位则属于硬件复位,其会将绝大部分外设(模拟、时钟和外设)电路复位,更接近直接运行应用程序的情况。
已完成
数据加载中