Search code examples
cembeddedstm32

C Embedded - What is the correct way for allocating memory and building around that memory inside STM32?


I am building a system with STM32 that uses a device that needs to be calibrated (the data can be stored in one 32 bit register). Since I am still building and updating the code, I ideally would like the region to stay in the same place so every time I build and power on it doesn't have to recalibrate. Obviously its a given that the MCU doesn't initialize the values in that region given it's calibration data.

Right now I've just picked a far flung address inside the flash region, and am hoping the compiler doesn't write over it. It works perfectly, but it feels like there is a proper way to block out memory from the compiler side.


Solution

  • Very straight forward process. Firstly, a memory region is established in the linker (.ld) file:

    MEMORY
    {
      RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 24K
      FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 128K
      CALIBRATION (rx) : ORIGIN = 0x0801FFE0,   LENGTH = 8 /* new 8 byte section */
    }
    

    Then in the sections part a few lines down, I added:

    .calibration (NOLOAD) :
      {
        . = ALIGN(4);
        KEEP(*(.calibration))
        . = ALIGN(4);
      } >CALIBRATION
    

    The key part is the NOLOAD, which ensures that the values inside are not initialised on startup.

    Then in the main file, you just need to add the pointer and address for reading and writing:

    volatile uint32_t *calibration_value = (uint32_t *)0x0801FFE0; // create pointer at address
    InitialCalib = *calibration_value; // use deferenced pointer to access data