简介
Flash BootLoader 简称FBL。在车载中主要用于对MCU APP程序进行升级或安全启动。
外界通讯方式
CAN:基于UDS标准协议进行升级。
SPI/UART:用于MCU 与SOC间通讯,也可以用于MCU升级,主要是基于自定义协议。
以太网ETH:基于DOIP协议升级。
分区
APP和 FBL其实是两个独立的工程,分别处在Fash的两个段,一般通过Id 文件来指定对应的地址段FBL处在MCU 的启动入口处,MCU启动时,优先启动FBL,FBL再判断是否跳转到APP。
升级流程
从FBL开始的升级流程如下图,是否从APP跳转过来就是是否有升级请求的意思,如果是从APP跳转过来就肯定是有升级请求。中间如果某一步指令或者执行错误,都将停留在该步骤内。并且有些设计里面会加入看门狗,超过一定时间没有跑完全过程就看门狗reset。为了区分程序是运行在APP还是FBL里面,无用的位置将采用不同的填充方式,譬如APP使用0xAA填充,FBL使用0xCC填充。
有些芯片不能直接操作Flash,需要用到FlashDrive才能操作,就要先把FlashDrive下载到RAM,再通过FlashDrive来执行擦除、读写等操作。
拓展方案
AB升级
为了解决升级过程中途掉电导致APP不能用,可以采用AB升级方案,其实就是分多一个APP分区,也是通过判断MagicFlag就可以决定跳转到哪个APP,并且可以做到无感升级。
譬如APP_A在执行的时候,升级APP_B,只要分多一个线程来执行就行。
PBL
为了解决FBL不能升级的问题,引入PBL概念,可以用来升级FBL,看下面的图就知道大概怎么设计。
验签
有一些校验方案会用到验签:
1、OEM会生成两个东西。Production Key自己保留,也叫私钥。Development Key给MCU供应商,也叫公钥。
2、MCU供应商把带有Development Key的VBF roothash给到OEM。
3、OEM根据VBF roothash和Production Key生成新的VBF文件,也就是公钥和私钥弄在一起,给回供应商写到Flash里面。
软件下载的时候,诊断仪会发送根据Production Key生成的签名,MCU供应商根据手里的Development Key和新的VBF文件跟Production Key生成的签名进行校验,通过了才完成解密和认证。
MagicFlag
其实还有一个问题,就是MagicFlag是保存在Flash还是RAM?
很多人会认为保存在Flash比较好,掉电不丢失,一开始我也是这么认为的,但是前几年在对NXP新出的K3芯片操作的时候发现这条路很难走。因为这个芯片不允许直接操作Flash,只能通过FlashDrive来操作Flash,如果MagicFlag是保存在Flash的话,APP和FBL都需要集成FlashDrive,因为当时设计用到达芬奇,里面的代码非常难懂,移植起来非常困难,以我现在的能力都做不到,就更别说几年前了。
所以当时使用的方法是,APP将MagicFlag写入到RAM里面,反正跳转的时候不掉电,RAM里面的MagicFlag还在,FBL依然能够判断。
于是就遇到了开发过程当中的一个问题,APP将MagicFlag写入到RAM里面,跳转到FBL之后,MagicFlag居然没了!
APP跳转FBL丢失MagicFlag问题
App跳到FBL有如下三种方式:
软件Reset:通过控制寄存器,实现软件Reset。理论上该方法不会导致RAM数据丢失
硬件Reset:通过控制外部TLE926x Watchdog实现MCU芯片供电reset。该方法类似断电/上电过程,会导致所有RAM数
据丢失
跳转FBL入口地址:通过地址跳转的方式,该方法可能导致某些寄存器未初始化,直接跳到FBL,产生异常。
通过对地址打断点的方式,分析到FBL和App的启动代码都会对RAM进行初始化
如下FBL启动代码,对照规格书。当PowerOn时,初始化0x20400000~0x2044FFFF地址范围,里面就包括了MagicFlag的地址。
结合汇编和ld文件,发现App启动汇编 会无条件 初始化 0x20400608~0x20443000地址。所以
App定义的MagicFlag不能为这段地址内。
这样就好解决了,把MagicFlag写到别的地址里面去0x20400600开始的8字节。
于是开始调试验证,调试方法如下:
1.下载FBL,通过CANQe升级App,完成后,程序跳转到App中。
2.在Magic Flag位置加断点,CANoe,发送10 02指令,发现代码可以停下来,单步运行,Magic Flag值能够正确置上
3.继续运行App,程序执行Software Reset。
4.程序停在FBL 入口位置,此时发现Magic Flag值被清零了。那是不是Software Reset 导致 RAM被清零?
分析memory地址发现,当SoftwareReset时,只有刚写入的数据被清零,周边的数据未变化和清零。
重新测试,在Magic flag 被改变时,通过S32KDS把 0x20400608地址手动改为0x12345678,然后SoftwareReset。发现只有Magic flag值被清掉,0x20400608地址值保持不变。所以得出结论:Software Reset 让代码里面运行的值被清掉,但是手动设置的值没有清掉。
将这个诡异的现象反馈给NXP,NXP反馈可能是RAM cache导致的。
App启动时,默认打开RAM cache,通过如下代码init。
从代码可以发现0x20400000~0x2043FFFF 地址段启用了RAMcache。之前Magic Flag地址段刚好在里面,导致Magic Flag值被写入了Cache中,为实际存储到RAM里。
所以再挑别的内存区域,来保存Magic Flag就行了。