cancel
Showing results for 
Search instead for 
Did you mean: 

SMT32CubeIDE - How to store a const struct at a specific flash memory address?

ERODR.1
Associate III

I'm trying to store a const struct at a specific flash memory location using the STM32CubeIDE. I tried appending the __attribute__((at(address))) to the struct initialization, but the compiler ignores it: "warning: 'at' attribute directive ignored [-Wattributes]"

const runtimeParams params __attribute__((at(0x0801F800))) = {
  // ... initialization values
};

What would be the correct way to accomplish this?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

There's not an easy way to do this in GCC. You either need to create a separate section in the linker to place the code, or use a pointer to store it somewhere directly while ensuring nothing else lives in that space.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

8 REPLIES 8
TDK
Guru

There's not an easy way to do this in GCC. You either need to create a separate section in the linker to place the code, or use a pointer to store it somewhere directly while ensuring nothing else lives in that space.

If you feel a post has answered your question, please click "Accept as Solution".
ERODR.1
Associate III

Thanks for your input. I created a new section in the linker as suggested.

ERODR.1
Associate III

For anybody else wondering how to do it. I edited the STM32F072CBTX_FLASH.ld to add a new section as below:

  /* Runtime parameters section in FLASH */
  _params_start_address = 0x0801F800;
  
  .params _params_start_address :
  {
    . = ALIGN(4);
    KEEP (*(.params))
  } >FLASH

And then specified the section attribute in the const initialization as follows:

const runtimeParams __attribute__((section (".params"))) params = {
  // ... Initialization values
};

This creates an overlap with the .rodata for stm32f030, how do you get around this?

 

 

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 8K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 64K
}

 

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 8K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 64K
  PARAMFLASH (rx) : ORIGIN = 0x801F800,   LENGTH = 2K
}

.params _params_start_address :
  {
    . = ALIGN(4);
    KEEP (*(.params))
  } >PARAMFLASH

This should be one step closer to what you want to achieve.

I assume however, that you want to keep the config data when flashing a new program. If this is the case, don't declare the structure as const, just make sure that the address is unused (outside of MEMORY ranges), then do this:

#define cfg_in_Flash (*(const struct cfgdata_ *)(CFG_ADDRESS))

 

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Thank you, actually my flash is only 64K and the setting area that I want to allocate is 1K. Now this setting area needs to be at a perticular location in the flash. I am able to compile the whole thing now with at attribute. But it doesn't place the setting block in the correct location. I just need to keep the block in correct position. Is it possible to do it without changing the code area?

Use the 2nd solution above, just make sure that your code ends before CFG_ADDRESS.

If you use real STM32F103C8T6, you may store the data at 0x801f800 - end of 128 KiB Flash.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I want to try out your second solution, but it is not clear to me how do I use the defined cfg_in_flash? 

I am using this 1K area for configuration memory which is required written by the application of required. So this area needs to be reserved and rest of the code should be unchanged during reconfiguration. Please help me understand how it can be implemented.