Embedded Cortex M3从应用程序跳回到引导加载程序,再跳回到应用程序

Embedded Cortex M3从应用程序跳回到引导加载程序,再跳回到应用程序,embedded,bootloader,iar,firmware,cortex-m3,Embedded,Bootloader,Iar,Firmware,Cortex M3,我有一个引导加载器和一个固件,从引导加载器到固件的初始跳转就像一个charme,但是当我有从应用程序跳回的场景时,制作一些东西并跳回我的应用程序。在那里,我遇到了一些奇怪的问题,最终导致了一个严重的错误。如果我通过IAR中的_enable_interrupts()激活中断,就会出现这个问题 清除和重置所有寄存器的正确寄存器是什么? 我已将MSP和PC设置为应用程序/引导加载程序的开头 这是必要的,我不使用NVIC_Systemreset的目的 希望有人能帮我解决这个问题?有一个关于引导加载程序的

我有一个引导加载器和一个固件,从引导加载器到固件的初始跳转就像一个charme,但是当我有从应用程序跳回的场景时,制作一些东西并跳回我的应用程序。在那里,我遇到了一些奇怪的问题,最终导致了一个严重的错误。如果我通过IAR中的_enable_interrupts()激活中断,就会出现这个问题

清除和重置所有寄存器的正确寄存器是什么? 我已将MSP和PC设置为应用程序/引导加载程序的开头

这是必要的,我不使用NVIC_Systemreset的目的

希望有人能帮我解决这个问题?

有一个关于引导加载程序的问题

除了上述模式之外,用户还可以执行引导加载程序 通过从用户代码跳转到系统内存。跳跃前 要启动加载程序,用户必须:

  • 禁用所有外围时钟
  • 禁用已用锁相环
  • 禁用中断
  • 清除挂起的中断
这就是为什么在激活中断时引导加载程序会崩溃

编辑

要寻址@Clifford STM32,系统引导加载程序将使用go命令跳转到主定义地址退出。这个地址应该是重置向量not main,这样堆、堆栈和FW将被正确初始化。之后,您可以将system_重置为已知的硬件状态,或者必须完全配置应用程序中使用的外围设备,因为它们在引导加载程序使用后未设置为重置状态

注意:如果选择执行Go命令,则外围设备 引导加载程序使用的寄存器未初始化为默认值 在跳转到用户应用程序之前重置值。他们应该是 在用户应用程序中重新配置(如果使用)。那么,如果IWDG 在应用程序中使用时,IWDG预分频器值必须为 适应于满足应用的要求(自 预分频器已设置为其最大值)。对于某些产品,并非所有产品 设置重置值。有关更多信息,请参阅已知 每个产品的引导加载程序版本的详细限制


很抱歉反应太晚

经过更多的调查,我发现了问题。 关于我所做的更多澄清,以下是你的评论中也提到的几点

  • 禁用所有外围设备
  • 解除锁相环
  • 禁用所有中断
  • 清除所有挂起的中断
不幸的是,我忘了提到我们使用EMBO。 这就是问题所在。这是核心寄存器

在控制寄存器中有一个位集:SPSEL 如果该位设置为“1”,则embOS在正常操作中出现问题。 解决方案很简单:

__设置_控制(0x0)


当这被称为从embOS跳到引导加载程序再跳回到embOS时,效果非常好。

请提供更多详细信息,如:在引导加载程序中跳到哪里,如何返回,在应用程序中要返回哪里,遇到什么问题?为什么不使用
NVIC\U SystemReset
?这是迄今为止最简单的方法。这可能是一个X-Y问题-您试图避免对一些未说明的问题进行
NVIC\u SystemReset
,而您的解决方案不起作用。也许避免
NVIC_SystemReset
是必要的,但了解你的假设原因可能会给你一个更好的解决方案。虽然Julien的答案可能是关于钱的,但也不清楚如何“跳回”引导加载程序-例如,如果使用了
main()
地址的JMP,引导加载程序将在应用程序的C运行时环境(堆栈、堆、库状态)中运行,这也可能导致问题。通常,从重置开始,将有硬件(PLL、外部内存接口等)初始化、C(或C++)运行时初始化,然后是
main()
。您至少需要从运行时初始化开始,只要引导加载程序没有硬时钟速度依赖项。听起来您可能没有意识到,如果不更新指向向量表的指针,或者在幕后使用重新映射来更改它,您就无法使用中断;如果返回引导加载程序,则必须撤消该更改。很可能重置是返回引导加载程序的最佳方式,尤其是在您没有编写引导加载程序的情况下;事实上,一般建议在每个方向上使用重置;当进入应用程序时,您设置一个标志(可能在RTC寄存器或RAM中,您排除在清除之外),在启动和分支的早期检测该标志,而不是进行任何芯片配置。