【问题标题】:STM32 Current Flash Vector AddressSTM32 当前 Flash 向量地址
【发布时间】:2019-07-02 11:54:00
【问题描述】:

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

【问题讨论】:

  • 两个程序是否都将 SCB->VTOR 设置为不同的值?
  • 实际上,我将 FLASH 拆分为两个空间,并且我有一个正在运行的程序,它可以自行更新。它会将新固件下载到 FLASH 中的另一个位置并重新定位 START VECTOR。并且程序将从FLASH中的高位地址开始。但是下次新固件要更新自己时,必须使用FLASH的低地址来写入新固件。旧固件填充的地址。然后将起始向量更改为低地址。那么我需要知道当前程序在哪里编程?! FLASH 的上部还是下部?
  • 这听起来很复杂。我过去这样做的方法是让更新程序写入图像#2,引导加载程序检查图像#2的crc,如果它与图像#1的crc不同,它将#2复制到#1上。这样代码总是在同一个地方运行,而图像#1 总是被执行的。
  • 按照您目前计划的方式进行操作,您需要知道程序何时链接,无论它是从高闪存还是低闪存运行,还有很多问题要解决。
  • @mban 链接寄存器可能会有所帮助,但我怀疑堆栈指针会有多大用处,但我会假设两个应用程序都会使用整个 RAM 区域。

标签: memory stm32 ram bootloader flash-memory


【解决方案1】:

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

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

  1. 使用某种类型的数据完整性检查(如 CRC)检查自身。
  2. 检查应用程序
  3. 跳转到应用程序。

引导加载程序还将在应用程序空间中对应用程序进行编程,并在跳转之前验证它们是否已正确编程。 Colin 给出了一些很好的建议,即在将 CRC 附加到 hex 文件之前,在闪存空间中对其进行编程以验证应用程序。

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

  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 附加到 hex 文件并将其编程到闪存空间,请记住记下该位置并将其告知链接描述文件,以便您以后可以参考这些地址以检查完整性。

在你检查了一切,确定可以进入应用程序后,你可以使用一些ARM程序集跳转到起始应用程序地址。在跳转之前,请确保禁用引导加载程序中启用的所有外设和中断。正如 Colin 所提到的,这些将共享 RAM,因此取消初始化所有已使用的内存很重要,否则最终会出现硬故障。

此时,该程序使用了另一个由链接描述文件布局的十六进制文件,因此只要您有正确的向量表偏移量,它就应该按计划开始执行,这完全符合您的问题。

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


/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to relocate your vector Table in
     Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
                                   This value must be a multiple of 0x200. */
/******************************************************************************/

在编程之前,请确保您了解使用 STM 文档从微观方面的预期。此芯片中的向量表只能是0x200 的倍数。但要回答你的问题,这个地址可以由几件事来确定。您的内存映射,最终,您将拥有对它的硬编码引用作为定义。你可以从那里弄清楚。

希望这对您的申请有所帮助并祝您好运。

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 2021-12-30
    • 2016-07-11
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多