我正在为STM32F051在引导加载程序上做一个项目,该项目会跳转到其他内存位置的应用程序。这部分工作正常。我遇到的问题是,我已经在FLASH中定义了一个位置来放置应用程序的变量。这些变量将是诸如版本号,时间戳等之类的东西,它们是应用程序用作信息的基本变量。
我想允许引导加载程序访问这些变量而不尝试设置它们。当我在加载应用程序后对引导加载程序进行更改(或者即使我没有更改),然后尝试对其进行调试时,它失败了,因为它试图在已经包含数据的应用程序变量闪存空间中执行写操作。
Bootloader链接器片段:
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库
所以我的问题:
是否有一种方法可以将应用程序变量的内容分配给引导加载程序中的变量,而无需确切知道它位于哪个内存地址?
答案 0 :(得分:1)
至少应该有一些应用程序和引导程序都知道的指针(4个字节)。这应该是功能或结构的指针。 通常,我为通用数据/设置分配FLASH的最小页面。在STM32F051中,所有页面的大小都相同,因此您可以分配最后一页
#define SETTINGS_PAGE_NUM 63
#define SETTINGS_ADDR 0x0800FC00
#define settings ((struct settings_s*)(SETTINGS_ADDR))
提供地址的另一种方法-分配链接脚本的PROVIDE
。我建立第一个应用程序并通过bash脚本创建PROVIDE的列表。当我购买第二个应用程序时,我只是将此列表包含在链接脚本中。因此,大概是这种方式对您的问题回答“是”。