1

我正在为 STM32F051 的引导加载程序做一个项目,它跳转到不同内存位置的应用程序。这部分工作正常。我遇到的问题是我在 FLASH 中定义了一个位置来放置应用程序的变量。这些变量可以是版本号、时间戳等,应用程序用作信息的基本变量。

我想允许引导加载程序访问这些变量而不尝试设置它们。当我在加载应用程序后对引导加载程序进行更改(或者即使我没有)然后尝试调试它时,它会失败,因为它尝试在已经包含数据的应用程序变量闪存空间中执行写入。

引导加载程序链接器片段:

MEMORY
{
VTRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 0xc0  /* First part of RAM is reserved to the vector table */
RAM (xrw)       : ORIGIN = 0x200000c0, LENGTH = 8K - 0xc0

FLASH (rx)          : ORIGIN = 0x08000000, LENGTH = 12K
APPLICATION (rx)    : ORIGIN = 0x08003000, LENGTH = 9K
APPLICATION_VARS(rx): ORIGIN = 0x08005400, LENGTH = 1K
BCKP(rx)            : ORIGIN = 0x08005800, LENGTH = 9K
BCKP_VARS(rx)       : ORIGIN = 0x08007C00, LENGTH = 1K
}
.application_vars :
{
   KEEP(*(.application_vars .VERSION_NUMBER))
   KEEP(*(.application_vars .VERSION_TIMESTAMP))
   KEEP(*(.application_vars .VERSION_LOADED_TIMESTAMP))
   KEEP(*(.application_vars .VERSION_FAULTY))
   *(.application_vars *);
  } > APPLICATION_VARS

应用程序的链接器是相同的,只是它不包含:

FLASH (rx)          : ORIGIN = 0x08000000, LENGTH = 12K

BCKP(rx)            : ORIGIN = 0x08005800, LENGTH = 9K
BCKP_VARS(rx)       : ORIGIN = 0x08007C00, LENGTH = 1K

这是引导加载程序中用于分配变量的代码行

char application_version_number[5] __attribute__((section(".application_vars.VERSION_NUMBER")));

在应用程序中我分配它

char version_number[5] __attribute__((section(".application_vars.VERSION_NUMBER"))) = "v1.0";

我知道我可以使用指针指向“VERSION_NUMBER”的确切内存地址,但我总是需要知道它在哪里。如果我想更新应用程序,我必须确保每个变量始终位于旧版本中的同一位置。

我正在使用“用于 stm32 的系统工作台”、“CubeMX”和 HAL 库

所以我的问题:

有没有办法将应用程序变量的内容分配给引导加载程序中的变量,而无需确切知道它在哪个内存地址中?

4

1 回答 1

1

至少应该有一些应用程序和引导加载程序都知道的指针(4 个字节)。这应该是指向函数或结构的指针。通常我会为常见的数据/设置分配一个最小的 FLASH 页。在 STM32F051 中,所有页面都具有相同的大小,因此您可以分配最后一页

#define SETTINGS_PAGE_NUM 63
#define SETTINGS_ADDR 0x0800FC00
#define settings ((struct settings_s*)(SETTINGS_ADDR))

提供地址PROVIDE的另一种方法 - 分配链接描述文件。我构建了第一个应用程序并通过 bash 脚本创建了 PROVIDE 列表。当我构建第二个应用程序时,我只是将此列表包含在我的链接器脚本中。因此,这种方式可能是对您的问题的回答“是”。

于 2019-10-06T16:25:48.653 回答