ARM GCC force variable to be loaded in flash even if unused

I have a AES variable that would like to force-load it to specific address in the bootloader application (Cortex-M7 based app). ARM GCC 10.3.1 compiler. it will be used in the later stage, by the main app. It is considered UNUSED in the bootloader app.

Linker script memory definition

/* Specify the memory areas */
MEMORY
{
    FLASH_FSBL          (rx)    : ORIGIN = 0x08000000,  LENGTH = 126K
    FLASH_FSBL_AESKEY   (rx)    : ORIGIN = 0x0801F900,  LENGTH = 256
}

I defined my own region for AES key

    /* Section for AES key */
    .aes_key_sect :
    {
        PROVIDE(region_aes_key_start = .);
        KEEP (*(.aes_key_sect))
        PROVIDE(region_aes_key_end = .);
    } >FLASH_FSBL_AESKEY

In boot code, I have:

#define LOCATION_AES_KEY       __attribute__((section(".aes_key_sect")))

LOCATION_AES_KEY static uint8_t aeskey_const[] = {
#include "../../../aes256_key.txt"
};

When compiled, I see that it was not included in the build

      FLASH_FSBL:       24444 B       126 KB     18.95%
FLASH_FSBL_AESKEY:          0 GB         0 GB

The only way to do it so far, is to dummy-access it in the init function, like so:

void init() {
    const volatile uint8_t* k1 = aeskey_const;
    (void)*k1;
}

When compiled, I see it is part of build:

Memory region         Used Size  Region Size  %age Used
      FLASH_FSBL:       24452 B       126 KB     18.95%
FLASH_FSBL_AESKEY:          32 B         0 GB

is there no better way than this? if I change definition to const, there is no effect.

>Solution :

GCC provides special attributes not defined in the C standards, as you apparently know. One such attribute is "used" that tells the compiler the object is in fact needed and prevents it from removing it. The usage in your case would be :

__attribute__((__used__)) LOCATION_AES_KEY static uint8_t aeskey_const[] = {
#include "../../../aes256_key.txt"
};

Leave a Reply