Electronic – Put saved data in flash of STM32 at the end of all other sections

eepromflashstm32

I want to emulate EEPROM over flash of STM32F103. Is there a way to use all free flash instead of the only page? How can I initialize starting point of my EEPROM emulation so that it would be after all sections? I tried to add section after .text like

.text: ...

.myvars :
{
. = ALIGN(1024);
KEEP(*(.myvars));
KEEP(*(.myvars*));
} > rom

and define variable as

__attribute__((section(".myvars"))) static const flash_storage Flash_Storage = {
    .magick = "1234567890absdef0987654321",
    .all_stored = USERCONF_INITIALIZER
};

but it doesn't helps me: I see some more data after this structure in binary dump.

UPD: the solution of this problem quite simple. The section .myvars should be after last section in ram, i.e. after .data!

Best Answer

The simplest solution of such problem is to put the section .myvars after latest section in ram. In my case it should be after section .data. The full linker file:

MEMORY
{
    rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}

ENTRY(reset_handler)

SECTIONS {
  .vector_table 0x08000000 :
  {
    _sisrvectors = .;
    KEEP(*(.vector_table))
    /* ASSERT(. == _isrvectors_tend, "The vector table needs to be 84 elements long!"); */
    _eisrvectors = .;
  } >rom

  .text :
  {
    . = ALIGN(4);
    _stext = .;
    *(.text*)
    *(.rodata*)
    . = ALIGN(4);
    _etext = .;
  } >rom

  .ARM.extab :
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } >rom

  .ARM : {
    *(.ARM.exidx*)
  } >rom

  .data :
  {
    . = ALIGN(4);
    _sdata = .;
    *(.data*)
    . = ALIGN(4);
    _edata = .;
  } >ram AT >rom

  .myvars :
  {
    . = ALIGN(1024);
    KEEP(*(.myvars))
  } > rom

  _ldata = LOADADDR(.data);

  .bss :
  {
    . = ALIGN(4);
    _sbss = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;
  } >ram
}

PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));

Here is the code.