我的主程序是基于UCOS2的操作系统,现在需要在程序里加入bootloader功能,但是遇到了一个问题。
程序在运行ModifeMSP(myaddr)的时候就直接跑飞了,请问是怎么回事?
在地址myaddr处,有自行开发设计的bootloader程序,此程序在非操作系统下运行正常。
谢谢
我的主程序是基于UCOS2的操作系统,现在需要在程序里加入bootloader功能,但是遇到了一个问题。
程序在运行ModifeMSP(myaddr)的时候就直接跑飞了,请问是怎么回事?
在地址myaddr处,有自行开发设计的bootloader程序,此程序在非操作系统下运行正常。
谢谢
跑飞到哪里去了?ModifeMSP(myaddr)这个函数是做什么的呢?
如果只是要跳转到myaddr处,剩下的都由bootloader处理,只需要跳转过去就行了
(*((void (*)(void))myaddr))();
抱歉之前没有说清除,之所以问ModifieMSP的作用是想确定这个函数的作用是用myaddr修改MSP的值,而不是用myaddr地址中的值修改MSP。
如果myaddr的值不是MSP的地址而只是存MSP地址的地址,这句代码应该是:
ModifieMSP(*((unsigned long *)myaddr));
这样才能拿到正确的SP地址。
首先,我的myaddr地址是FLASH的绝对地址,并且在myaddr地址上包含有程序重新运行需要的向量表。
但是在执行程序跳转的时候,且发生了程序跑飞,最终的原因是:
CM3系列MCU在执行ModifeMSP(myaddr),然后(*((void (*)(void))myaddr))()后,按理论将,MSP正确,PC指向正确,必将开始新程序执行。当我忽略了一点。按以上步骤完成的程序跳转,芯片所有外设及寄存器并没有被复位,也就是说,如果Bootloader程序中没有全部重新定义外设为无效,那么跳转前程序中使能的外设将可以继续工作,因此,一旦这些外设发生中断之类的情况,将直接导致Bootloader程序发生硬件错误(我所谓的跑飞);
所以,最直接的解决办法是,在跳转之前将程序中开启的所有外设都关掉,特别是中断,一定要逐个进行关闭。
我在问题中提到的ucos跳转失败,而单线程程序测试却正常的问题在于,我虽然关闭了程序中设计的中断,但还是忽略了一点:ucos用到了芯片的systick,这个非芯片片内外设,需要用函数注销。
谢谢