Memory STM32当前闪存向量地址

Memory STM32当前闪存向量地址,memory,stm32,ram,bootloader,flash-memory,Memory,Stm32,Ram,Bootloader,Flash Memory,我正在使用STM32F103开发一个双操作系统,我有两个单独的程序,在不同的闪存位置编程。如果两个程序都是相同的,那么知道它们运行的唯一方法就是通过它的起始向量地址。 但是我如何才能在STM32中读取当前程序的开始向量地址呢?在阅读注释后,听起来你想要的是一个引导加载程序。如果您的目标是拥有两个不同的应用程序,一个用于主处理和实时处理,另一个用于编写新固件,那么您需要在默认引导闪存空间中创建引导加载程序 引导加载程序基本上只做一些事情,其他的都是额外的 使用某种类型的数据完整性检查(如CRC)进

我正在使用STM32F103开发一个双操作系统,我有两个单独的程序,在不同的闪存位置编程。如果两个程序都是相同的,那么知道它们运行的唯一方法就是通过它的起始向量地址。
但是我如何才能在STM32中读取当前程序的开始向量地址呢?

在阅读注释后,听起来你想要的是一个引导加载程序。如果您的目标是拥有两个不同的应用程序,一个用于主处理和实时处理,另一个用于编写新固件,那么您需要在默认引导闪存空间中创建引导加载程序

引导加载程序基本上只做一些事情,其他的都是额外的

  • 使用某种类型的数据完整性检查(如CRC)进行自我检查
  • 检查应用程序
  • 跳转到应用程序
  • 引导加载程序还将在应用程序空间中对应用程序进行编程,并在跳转之前验证它们是否正确编程。科林给出了一些很好的建议,在十六进制文件在闪存空间中编程以验证应用程序之前,先将CRC附加到十六进制文件中

    有几件事需要注意。第一个是链接器脚本,这非常重要。链接器脚本将用于将输入对象映射到输出对象,然后根据该脚本确定它们进入的内存空间。对于这两个应用程序,您需要创建一个内存映射,说明您希望这两个程序如何放置在闪存空间中。从这一点上,您可以为这两个程序生成链接器脚本,以便在您认为程序可接受的闪存空间的参数范围内生成十六进制文件。您拥有的每个项目都有自己的链接器脚本。示例如下所示:

      LR_IROM1 0x08000000 0x00010000  {    ; load region size_region
      ER_IROM1 0x08000000 0x00010000  {  ; load address = execution address
       *.o (RESET, +First)
       *(InRoot$$Sections)
       .ANY (+RO)
      }
      RW_IRAM1 0x20000000 0x00018000  {  ; RW data
       .ANY (+RW +ZI)
      }
    }
    
    这将提供应用程序使用的RAM以及应用程序的起点

    之后,您可以启动引导加载程序,并向其提供有关应用程序空间的信息,以便进行跳转和编程。同样,这一切都是由内存映射和两个应用程序的链接器脚本决定的。您需要在链接器中为CRC和长度添加一个单独的条目,以便将计算值和存储值进行比较。无论您使用什么工具将CRC附加到十六进制文件并将其编程到闪存空间,请记住记下位置并告知链接器脚本,以便您可以引用这些地址,以便稍后检查完整性

    在检查所有内容并确定可以转到应用程序后,可以使用一些ARM程序集跳转到起始应用程序地址。在跳转之前,请确保禁用引导加载程序中启用的所有外围设备和中断。正如科林所提到的,它们将共享RAM,所以您必须对所有使用的数据进行反初始化,否则,您将最终导致硬故障

    在这一点上,程序使用了另一个由链接器脚本设置的十六进制文件,因此它应该按照计划开始执行,只要您有正确的向量表偏移量,这就完全进入了您的问题

    至于你关于“闪存向量地址”的问题,我认为你真正的意思是你的中断向量表地址。中断向量表是内存中的一种数据结构,它将中断请求映射到中断处理程序的地址。例如,这是PC寄存器在硬件中断触发时获取下一个可用指令地址的地方。通过在几行汇编代码中跟踪ARM管道,可以看到这一点。此表的每个条目都是处理程序的地址。此偏移量必须与应用程序对齐,否则您将永远无法进入主函数,程序将位于应用程序空间中,但由于所有处理程序地址都未知,因此无需执行任何操作。这就是
    SCB->VTOR
    的作用。它是一个向量中断表偏移地址寄存器。在这种情况下,您可以做一些事情。幸运的是,这些都是硬编码在STM生成的文件“system_stm32(xx)xx.c”中(xx是您的微控制器变体)。有一个名为
    VECT\u TAB\u OFFSET
    的定义,它是向量表的内存映射中的偏移量,用所选的值分配给
    SCB->VTOR
    寄存器。中断向量表将始终位于主应用程序的起始地址,因此对于引导加载程序,它可以是
    0x00
    ,但对于应用程序,它将是应用程序空间的起始地址和微控制器的第一个可寻址闪存地址的减法

    
    /*************************杂项配置************************/
    /*!< 如果需要在中重新定位向量表,请取消注释以下行
    内部SRAM*/
    /*#定义向量选项卡#SRAM*/
    #定义向量选项卡偏移量0x00/*!<向量表基偏移字段。
    此值必须是0x200的倍数*/
    /******************************************************************************/
    
    在编程之前,请确保您了解使用STM文档从微观方面期望得到什么。该芯片中的矢量表只能是
    0x200
    的倍数。但要回答你的问题,这个地址可以由几件事决定。你的内存映射,最终,你会有一个硬编码的引用来定义它。你可以从那里找到答案


    希望这对您的应用程序有所帮助并祝您好运。

    这两个程序是否都将SCB->VTOR设置为不同的设置?实际上,我将闪存拆分为两个空间,我有一个正在运行的程序,它可以自我更新。它会将新固件下载到闪存中的另一个位置,并重新定位启动向量。程序将从FLASH中的上部地址开始。但是下一次,新的固件wan