AnsweredAssumed Answered

Forcing static initialized arrays into FLASH (not in SRAM)

Question asked by Lynn Linse on Dec 29, 2016
Latest reply on Dec 30, 2016 by gonzalez.laurent

THIS ISN'T A QUESTION - IS A RESULT.

 

I was having issues getting some static arrays to stay in FLASH, not SRAM. Since they NEVER change, allowing them to load into SRAM just means the exist in both flash & SRAM (aka: init'd values copied to SRAM). Since I feel the full solution isn't trivially obvious, I'll record it here for others.

 

I am using AC6/STM System Workbench and STM32L152RE, so my solution might be specific to the CGG used and default linker scripts.

 

The simple array was easy - just adding the CONST caused &data_flags to be in the FLASH (0x080XXXXX range) instead of SRAM (0x200XXXXX range).

static const uint8_t data_flags[] = {
    (DS_FLAG_PROTECT),                                  // DB_COUNTERS_CTBOT
    (DS_FLAG_PROTECT),                                  // DB_COUNTERS_CTWDG
    (DS_FLAG_PROTECT | DS_FLAG_MIN),       // DB_COUNTERS_CTDLY

 ...

};

 

However, tables of strings proved more challenging. The working solution was this:

static const char const *data_tags[] __attribute__ ((section (".rodata"))) = {
        "CT.BOT",                           // DB_COUNTERS_CTBOT
        "CT.WDG",                           // DB_COUNTERS_CTWDG
        "CT.DLY",                           // DB_COUNTERS_CTDLY

 ...

};

Despite the 2 x CONST, &data_tags continued to be in SRAM, as a table of FLASH pointers to constant strings. So &data_tag was in SRAM (0x200XXXXX range) while data_tag[0] was a pointer to flash (0x080XXXXX range). Adding the __attribute__ ((section (".rodata"))) phrase moved data_tag itself into FLASH nicely.  ".rodata" is in my STM32L152RETx_FLASH.ld file as the name of a FLASH section. You might need to change this if your linker file uses different names.

Outcomes