How to stock variables in FLASH memory

armflashmicrocontrollerstm32

I am working with a STM32 eval-board from STMicro which includes a ARM Cortex-M4 processor. I need a LUT for cosinus and sinus (read-only variables). I need to manage my RAM memory therefore I want to store these LUT in flash memory.

First: is it better to create a interpolate computation of cosinus/sinus or the FLASH reading is fast enough?

Secondly, how to put the variables in FLASH memory. ST provides some examples, but maybe, for my problem I just need to declare the LUT variables as static const and it will be like code?

Best Answer

The short answer is to declare your variable with the const keyword. If your MCU actually remembers the value of your const variable (i.e. your sine computation actually works), it pretty much has to be stored in flash memory, otherwise it would be lost at the first reboot after programming.

The long answer has to do with linker script. These scripts are MCU-dependant and tell the linker where to put what. Usually, this script is provided by the IDE, but you can write your own. On my STM32F4 setup, my linker script starts with a such a statement:

MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
    CCMRAM (xrw)    : ORIGIN = 0x10000000, LENGTH = 64K
    MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}

It says that the flash starts at address 0x08000000 and the RAM at address 0x20000000. These addresses can be found in the datasheet where the memory map is described. The rest of the script can get involved, but at some point something along these lines will be present:

.text :
{
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
} >FLASH

This says that all .text sections (that's how the compiler calls code section) and .rodata sections (that's how the compiler calls const variables) are to be put in the flash section.

As suggested above, the .map file is the primary way you can check what the linker puts where. You tell the linker to generate it using this option:

arm-eabi-gcc -Wl,-Map=my_program.map ...

You can search for your symbole inside this map file, see at which address it has been stored and check that against the memory map specified in the MCU datasheet.