诊断中的一些复位跳转
在一个刷写过整包软件的ECU中,在正常上电时ECU会自动跳转至APP软件的起始地址。如果ECU中只存在BTLD与APP软件,在ECU上电后跳转至APP的行为直接由BTLD控制。
而若是由BM和FBL共同组成的BTLD,软件的跳转则由上电后BM的状态机决定。本篇文章就简单概述下在BM&FBL方案中,由诊断服务导致的复位是如何进行的。
1. 0x11ECUReset服务
该服务顾名思义,本身就是为了使软件复位而设计的。那么我们可以确定该服务的目的为,使ECU重新上电,回到BM,而在BM中使ECU重新跳转至APP。
在该方案中,在ECU收到11服务的指令后,程序将跳转至
Dcm_Service11PostProcessor -> Dcm_ModeSwitchEcuReset(RTE_MODE_DcmEcuReset_EXECUTE)
在该Post函数中,通过配置模式切换接口,将全局中间量赋值为RTE_MODE_DcmEcuReset_EXECUTE,而在APP层的模式管理中,可选在该中间量为该值下的行为,例如给slave ECU发送复位指令,使Master与Slave同步进行复位。
而后,当满足BswM中设计的规则后,执行一系列复位准备工作后,通过Mcu_PerformReset实现复位。
2. 0x10会话控制的子服务1002
众所周知,想要进行诊断刷写的前提是通过1002使ECU进入编程会话,而此处进入编程会话便可等同地认为进入了BTLD。那么在BM&FBL的BTLD方案中,跳转的目标由BM进行判断,那么应该如何确保ECU在APP软件下收到1002,复位后能够跳转至FBL而非APP呢?
我们可以分为两个部分讨论这个流程。
2.1 APP中从收到1002到进行复位
其实这个过程与上文0x11服务导致的复位有些类似,但是与其不同的是,0x11服务需要跳转至APP,而1002服务需要跳转至FBL。我们可以这么考虑,复位后跳转至APP是ECU默认的行为,那么需要打破这个行为,是否应该额外做些操作?比如在复位前将某个Flag写入NvM。
基于这个思路,在收到1002后,由DCM负责的部分流程如图:
我们可以看到与0x11服务不同在于,除了将上文的全局中间量置了一个不一样的值之外,还额外的写入了一个MagicFlag。此处划重点,很重要。
在全局中间量被置上之后,可以设计另一个BswM的Rule,来处理1002带来的请求,在满足Rule的条件后,最终通过Action执行复位,重新来到BM。
2.2 BM如何确定目标
在BM状态机运行至FblBmState_CheckReprogFlag后确认MagicFlag,跳转至FblBmState_CallFbl_Entry,来到FBL。
在跳转至FBL后,通过FblBmClrMagicFlag将MagicFlag清除,以便后续复位能够重新跳转至APP。
FblBmState_CheckReprogFlag(FblBmChkFblStartMagicFlag) -> FblBmState_CallFbl_Entry
而若未通过1002的流程置上MagicFlag,则将去确认跳转目标后,执行跳转至相应的Target(APP或者Updater)。因此可以很好地区分0x11服务和1002服务。
FblBmState_CheckReprogFlag(FblBmChkFblStartMagicFlag) -> FblBmState_CheckFblLbt -> FblBmState_TargetListInit -> FblBmState_TargetCheck -> blBmState_CallTarget_Entry
其实也有其他方案供选择,但也是类似,可能在安全等级上会有些许差别。
3. 其他点
有心的读者也许会注意到最后执行Action中,有一个函数去写入一个GoodResetSignature,那么这个函数的作用,顾名思义就是去判断本次复位是否为正常情况的复位,比如我们说的0x11服务或者1002。而直接下电或者发送喂狗的问题,通过SBC切断芯片供电这样的行为,则会因为未设置该签名而被认为是所谓的“BadReset”。
在BM中,会在上电后确认这个签名的存在,若不存在则会对其进行计数,有些主机厂会要求在出现“BadReset”超过一定次数后,ECU自动跳转至FBL(BM中操作)。
这个点在有时APP出现问题无法跳转至FBL时能够帮上大忙。