下面的流程基本适用于所有的处理器,具体代码实现以Cortex-M为例。
在Cortex-M处理器上,Bootloader程序可以使用RTOS,也可以裸机实现,但是都要遵循以下流程。现在总结如下:
1.内核级,实现堆栈切换,跳转指令
2.NVIC级别,关闭所有的NVIC中断,清空所有pend的中断
3.具体芯片级,复位必要的外设,尤其是EXTI这类。SDRAM QSPI FLASH这类不需要复位,也不能复位。
下面着重讲解上面三级代码的具体实现,这3步是相互嵌套是关系。最终用户调用的都具体芯片级别的跳转函数。
1.内核级
实现函数hal_app_jump,该函数的C语言声明为:extern void hal_app_jump(rt_uint32_t u32AppAddr);
具体源码是汇编语言实现的,如下:
通过注释,可以很清晰的明白本函数的功能,该函数完整实现了bootloader的跳转流程,一些裸机场合,有些可能就不需要实现。
2.NVIC级别
先上代码,在根据代码来讲解。
可以看到NVIC级别,分5步,如果是非Cortex-M处理器,也是这5步,主要是对中断控制器清零,复位操作,避免在跳转的瞬间正好遇上了中断,造成乱跳转,跑飞。第五步
调用了步骤1的函数,执行真正的跳转。
3.具体芯片级别,
先上代码,再来谈具体实现。
具体芯片级别分了3步,该函数是H7下的例子。该步骤主要就是清除具体是外设,让CPU恢复到最初上电时的状态。第三步执行了NVIC级别的跳转函数。应用层只要调用该函数即可实现跳转。
如,如果要跳转到0x08020000处执行代码,则可以运行代码:rt_hw_app_jump(0x08020000),,严谨一点,跳转代码写如下:
4.其他问题
上面描述基本已经可以实现一个完整的BootLoader跳转了。细心的读者可能发现,复位外设,缺没有复位GPIO等外设,这里其实可能一些潜在隐患。如果BootLoader里面使用了GPIO中断,
在跳转的瞬间,由于静电干扰造成触发了中断信号,也可能造成跳转失败。这里比较妥当的做法当然的将EXIT的GPIO中断关闭,这通常是在按键驱动实现的。建议的是,如果在BootLoader中open了某个
外设,那么跳转前,请先close掉,在跳转。其它特殊的硬件,如有存在外部看门狗,不能关闭,在跳转前最好先喂狗一次,避免跳转的时候发生看门狗溢出,造成跳转不成功。
读完本文,读者是不是发现跳转没有那么简单。跳转异常基本都是跳转瞬间发生中断引起,只要控制好中断,就能控制好跳转流程。
hichard
很细致
赞!
补充一下,APP中也要留意,不要再把中断向量又给设回去了。
如果是向量中断的芯片,还是留意用了boot后,中断的入口和流程是否也需要做调整。
HWREG32()是什么函数啊,那个头文件里包含这个啊
@xiaoyuan_svip 。应该是自己定义的, rthw.h中 也有类似的定义