Gcc 针对损坏应用程序的引导加载程序策略

Gcc 针对损坏应用程序的引导加载程序策略,gcc,embedded,bootloader,cortex-m,Gcc,Embedded,Bootloader,Cortex M,我已经为Kinetis ARM Cortex-M4微控制器实现了一个引导加载程序 主应用程序(从0x10000开始)通过引导加载程序通过自定义RS232接口重新编程。我已经从引导加载程序和应用程序的角度实现了jumpToApplication和jumpToBootloader功能,到目前为止,所有功能都运行良好 我很想了解的一个策略是,如果主应用程序损坏,该怎么办 引导加载程序当前会检查主应用程序的堆栈指针和程序计数器,然后再决定是否跳转。但是,如果主应用程序已损坏,则会出现两个问题之一: 主应

我已经为Kinetis ARM Cortex-M4微控制器实现了一个引导加载程序

主应用程序(从0x10000开始)通过引导加载程序通过自定义RS232接口重新编程。我已经从引导加载程序和应用程序的角度实现了
jumpToApplication
jumpToBootloader
功能,到目前为止,所有功能都运行良好

我很想了解的一个策略是,如果主应用程序损坏,该怎么办

引导加载程序当前会检查主应用程序的堆栈指针和程序计数器,然后再决定是否跳转。但是,如果主应用程序已损坏,则会出现两个问题之一:

  • 主应用程序将挂起并使重新编程变得困难
  • 微控制器将重新启动,并将卡在
    引导加载程序
    应用程序
    引导加载程序
    (etc)循环中
  • 我有一个
    SharedData
    结构,它允许我在引导加载程序和应用程序之间共享数据(通过固定的RAM位置)。我已经考虑过在这个结构中添加一个
    rebootCounter
    ,当主应用程序中触发
    HardFaultInterrupt
    时,这个计数器将递增

    可以在引导加载程序中测试该值,并根据计数器值决定是留在引导加载程序中还是尝试启动应用程序

    是否有更多的“行业标准”处理方法

    更新

    为了澄清,提出此问题的最终原因是为了涵盖以下场景:

  • 引导加载程序在生产阶段通过JTAG编程到设备中
  • 主应用程序(最新版本)在测试阶段加载
  • 在测试阶段,出现断电或连接问题,设备仅部分编程
  • 再次通电时,引导加载程序将“假定”flash的主要部分中有一个有效的程序,并将“跳转”到此应用程序
  • 微控制器现在被困在无人地带,无法通过引导加载程序重新加载闪存,而无需打开产品外壳并通过JTAG重新闪存芯片——当产品进入现场时,我们无法做到这一点
  • 在引导加载程序编程阶段,固件逐字节进行编程和验证,以确保数据传输过程中没有损坏。如果在此阶段发生损坏(例如,由于USB集线器问题导致的坏数据包),则引导加载程序将继续接受重新编程命令

    更新#2

    以下帖子的思路似乎与此类似:


    首先,我建议在引导加载程序中添加一些等待固件更新进程启动指示器的延迟。我发展出了类似的东西;桌面应用程序定期发送开始字节,当您连接设备时,它将进入引导加载程序模式并再等待五秒钟以获取新固件信息;因此,闪存上是否有有效的主应用程序并不重要。
    另一种检查主应用程序是否存在的解决方案是,在固件更新过程擦除该扇区之前,使用闪存的特定扇区获取固件信息。固件更新成功后,将特定数据写入该扇区。在引导加载程序中,读取此扇区并验证闪存上是否有有效的应用程序

    我会在应用程序的末尾添加一些“magic”值(比如0xDEAD00D),然后只跳转到存在magic值的应用程序。您可以在
    0x10000
    处有一个指向该位置的指针


    为了使事情更加健壮,请在验证完成后对magic值进行编程。

    引导加载程序的唯一任务应该是对主应用程序闪存进行编程。为什么需要沟通?听起来好像你计划同时执行这两项任务。。。为什么要检查“主应用程序SP和PC”?如果引导加载程序发现主应用程序闪存已损坏,请尝试重新编程。这就是问题所在。“在没有实际运行主应用程序的情况下,如何确定主应用程序闪存是否损坏”,理想情况下,通过逐字节比较闪存。如果这不可能,则使用CRC32。我不明白如何“从应用程序返回引导加载程序”,同时引导加载程序将应用程序存储在哪里?在flash的另一部分?为什么闪光灯会更好?那么,您实际上在试图防止什么—数据保留?在将应用程序写入闪存时,闪存编程序列已经执行了字节验证(从地址0x10000开始)但我想说的是,如果在编程过程中电源被切断,然后当电路板重新通电时,我如何阻止应用程序被执行,因为从所有的意图和目的来看,它是损坏的。不知何故,我需要留在引导加载程序中,以允许进一步重新编程。我没有涉及到错误代码-这不是我的问题。然后-传输应用程序字节上计算的校验和。让引导加载程序根据编程数据计算校验和。比较一下。但无论如何,你们应该在flash中有一个字节,在那个里你们可以存储引导加载程序的“状态”本身——比如说,编程或者像普通的一样。因此,一旦它进入“编程”状态,它将不会在断电后进入应用程序,就像您描述的那样。@KamilCuk是的,我认为这就是解决方案。我认为将校验和存储在闪存的最顶端也是值得的,这样我就可以通过重启和电源循环来验证这一点。如果该校验和在固件更新开始时被擦除,然后在固件更新结束时存储(一旦BL比较并验证了校验和),则只能从引导加载程序执行已验证的应用程序。谢谢你,我实际上也在做类似的事情。我知道你