Search code examples
gccarmembeddedstm32bare-metal

GCC Absolute Location Data Placement & Potential Conflict With ROM


Let's say my device comes with pre-loaded data (4 bytes) in ROM at 0x08016F11. I am trying to preserve and access the data in that address in my application. To do this, I am placing a variable at an absolute address:

/* C application code */
__attribute__((section(".noinit"))) extern const uint32_t __TESTVALUE__; // __TESTVALUE__ defined in the .ld script

// Now accessing __TESTVALUE__ gives me the value at address 0x08016F11
/* GCC Linker Script */
MEMORY
{
  ROM (rx)  : ORIGIN = 0x08000000,  LENGTH = 1024K
}
PROVIDE(__TESTVALUE__= 0x08016F11); /* used in C code */

SECTIONS
{
    .isr_vector:
    {
        /* code here */
    } > ROM
    .text:
    {
        /* code here */
    } > ROM
    
    /*...*/
}

This code works perfectly fine and I'm able to see the value that is supposed to be in address 0x0816F111. But I have one concern. Since that address falls within the region of ROM, is it possible that one of the sections of ROM will overwrite the data at that address (e.g. will the linker place data from another section of ROM, like .text, at address 0x08016F11, or does it know to skip over it since I've done PROVIDE(__TESTVALUE__= 0x08016F11); ?

If it results in something getting overwritten, is there another way to achieve what I am trying to do besides splitting my ROM into multiple regions in the linker file? Perhaps a way to tell the linker file "please do not use this specified address range within flash"?

In summary:

  • Could the linker file potentially overwrite the data at 0x08016F11
  • If so, what is the best way to tell the linker file that this subset of flash is reserved?

Solution

  • The best way to do this would be to have your reserved region of flash completely separate from the rest of your code / data. Your code (or at least the vector table) MUST go at the start of flash. Typically the rest of your code and data would follow. If you need a "reserved" region that will not be touched by the linker, you'd place that at the very end of flash.

    You have two different "reserved" locations in your question: 0x08016F111 and 0x0816F111. Presumably one of these is a typo.

    Either way, it seems like an "odd" address (pun intended) for a 4-byte storage area, unless it is a byte array or similar.

    I don't even want to ask why your "device comes with pre-loaded data (4 bytes) in ROM at 0x08016F111." That seems very odd in itself. Is there a reason for this?