Hi all,
I've got a strange problems while trying to define some initialized data directly into FLASH, not in SRAM. General idea behind all these tricks was to enable program modules to be easily included or excluded from build process much like linux kernel modules do. Similar to linux I need to register some data as an array of pointers. To do this I defined macros which declare pointers to be placed in specific data section:
struct command cmd_x = {
.name = "command x",
.id = 123,
// etc
};
#define CMD_PTR(x) \
_Pragma("DATA_SECTION(\".commands\")") \
_Pragma("RETAIN") \
struct command *cmd_##x##_ptr = &cmd_##x;
Then I added section '.commands' to linker command file, to put all pointers into solid array with labeled begin and end margins. Actual data is constants so it is desirable to locate both real structures and their pointers into FLASH.
The problem arises when I try to put section .commands into ROM. Compiler sees that data is defined as modifiable and it places actual initialization to .cinit, just like if the section was going into SRAM. But linker places the section into FLASH accoring to my .cmd file. All this give me wrong data in runtime, all data is actually 0xff, since flash was erased and not updated from .cinit section.
Then I tried to force compiler to consider my data as read only, to eliminate initialisation bia .cinit. I tried to play with const keyword placing it around pointer declaration. But it does not work. Once I write something like
#pragma DATA_SECTION(".commands")
#pragma RETAIN
struct command *const cmd_reset_ptr = &cmd_reset;
I see the cmd_reset_ptr symbol is removed from .map file at all. Section becomes empty and is removed from output file. The only working solution for now is placement data into SRAM and initialization from .cinit. But this wastes SRAM resources!
How can I place initialized data into FLASH without wasting SRAM?