1

I am doing a project on a bootloader for an STM32F051, which jumps to an application in a different memory location. This part works fine. The issue I'm having is that I've defined a location in FLASH to place variables for the Application. These variables would be stuff like version number, timestamp, etc, basic variables for the application to serve as information.

I want to allow the bootloader to access these variables without trying to set them. When I make changes to the bootloader (or even if I don't) after loading the application and then try to debug it, it fails because it attempts to perform a write in the application variables flash space which already contains data.

Bootloader linker snippets:

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

The linker for the application is the same except it does not contain:

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

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

This is the line of code within the bootloader that I use to allocate the variable

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

In the application I assign it

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

I am aware that I could use a pointer to point to the exact memory address of "VERSION_NUMBER" but then I'd always need to know where it is. And if I want to update the application I'd have to make sure that each variable is always on the same spot it was in the old version.

I am using "System Workbench for stm32", "CubeMX", and the HAL library

So my question:

Is there a way to assign the contents of the application variable to a variable in the bootloader without needing to know exactly which memory address it is in?

protango
  • 1,072
  • 12
  • 21
  • Possibly related answers with possibly useful information: https://stackoverflow.com/questions/48561217/how-to-get-value-of-variable-defined-in-ld-linker-script-from-c/54728097#54728097 and https://stackoverflow.com/questions/55622174/is-accessing-the-value-of-a-linker-script-variable-undefined-behavior-in-c – Gabriel Staples Oct 07 '19 at 04:49

1 Answers1

1

At least there should be some pointer (4 bytes) that both of application and bootloader knows. This should be pointer to function or structure. Usually I allocate one smallest page of FLASH for common data/settings. In STM32F051 all page have same size, so you can allocate last page

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

Anoter way to give addresses - assigning PROVIDE of linker script. I build first application and create list of PROVIDE by bash script. When I buld second app I just include this list in my linker script. So, probably, this way is answer "yes" to your question.