在做嵌入式产品时,有时为方便更新设备程序(如远程更新或者只更新模块程序等原因),就要用到bootloader对设备进行必要的初始化,引导下载APP等。
STM官网下载的bootloader程序中并没有用到定时器等,很可能遇不到下面的问题。但是小猿猴如我等,会迫不及待的对其进行“魔改”,再经过二手三手,再加上运气不好,下面的问题就很容易暴露出来了:
现象:
bootloader 下载并跳转某些 app 程序时,app运行正常;
对于某些app来说,却根本跑不起来; app本身运行没有问题; bootlaoder+app运行,J-Link在线仿真时,发现报硬件错误;
原因之一:
bootloader 中开启了某些中断(并编写了中断函数),bootloader结束时未关闭该中断;
但是app程序中没有使用,也没有定义相关中断函数;
这时系统就会因为找不到中断函数入口而报硬件错误,即app跑飞了.
根源:
函数被调用时,系统根据其入口指针,将指令从ROM中加载到RAM中,函数执行完毕后就会释放这一块RAM。即全局变量定义后是存放在RAM中的,但是"函数"是存放在ROM中的,其入口地址(ROM地址)在编程的时候就确定了。
程序下载时,bootloader和app的二进制代码存放在ROM中不同的区域,彼此互不干扰,不会存在函数重定义的问题。作为app来说,会对系统的向量表进行重定位(可搜索查询“向量表重定位”的含义,这里就不说远了),并且是不直接调用bootloader中的某个函数的;但是这时系统已经被初始化了。
典型的如bootlaoder开启了定时器中断(Timer),但是app中没有用到定时器(Timer)更没有定义其中断函数,而已经被初始化了的系统在定时器中断时,会根据已经被重定位了的向量表去查找Timer中断函数,找不到的结果就是报硬件错误了。
当然,bootloader不稳定的原因有很多,如以太网、USB等app更新方式不同,可能的原因也会不尽相同。如果上述方法不能解决您的问题,那么哪天您解决了此问题时,还请分享出来,大家一起进步^^