In standard use your code goes into the 8 Kbytes of Flash memory and variables go into the 1 Kbyte of SRAM. Note that because a hex file represents a single byte as a pair of hexadecimal characters and contains some other information it will be over twice the size of the actual code that will be loaded, so a hex file a bit over 16K should load.
The most reliable place to find out of much Flash and SRAM your code uses is from the compiler. If you're using Atmel Studio 6 in the build output area if you scroll up you should see something like:
Program Memory Usage : 540 bytes 0.8 % Full
Data Memory Usage : 0 bytes 0.0 % Full
So the program memory use shows how much of the Flash will be used and data memory usage shows how much of the SRAM will be used.
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.
Best Answer
If you were writing assembler, you would decide which locations are used to hold which constants or variables, through org or similar directives.
When you are writing C, the C tool chain you're using will store stuff where it's been programmed to. Variables obviously tend to go in RAM, constants can go in either RAM or Flash, program tends to go in Flash.
It's all down to how the tool for that particular target processor has been designed, where it gets its instruction from where to put stuff. It might all be baked into the code, in which case you don't get any say, it goes where the tool chain's creators chose to send it. It may take directives from somewhere (source code, command line, make file, environmental variable) so that you can rebase stuff.
Read your specific documentation. It's not physics, it's all down to the whim of man.