cancel
Showing results for 
Search instead for 
Did you mean: 

Why are my constants in flash (custom linker section) reduplicated and how can I configure this?

MB_Inv
Associate III

In order to be able to read-out the version numbers of my firmware (and some magic number) from the .hex file (by some external update tool), I define some constants to be written to a custom flash sector:

/*
 * Constants which should go to specific locations in flash
 */
/** Firmware major version */
__attribute__((section(".inv_constants"))) \
      static const uint8_t SW_VERSION_MAJOR{0};
__attribute__((section(".inv_constants"))) \
/** Firmware minor version */
__attribute__((section(".inv_constants"))) \
      static const uint8_t SW_VERSION_MINOR{1};
/** Magic number for update tool */
__attribute__((section(".inv_constants"))) \
      static const uint32_t MAGIC_NUMBER{0x18273645};

In my linker script, I have added the following:

/* Memories definition */
MEMORY
{
  INV_CONST (r)   : ORIGIN = 0x08010008, LENGTH = 63K - 0xF
  FLASH (rx)      : ORIGIN = 0x08020000, LENGTH = 896K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
  CCMRAM (rw)     : ORIGIN = 0x10000000, LENGTH = 64K
}
.inv_constants :
  {
	  KEEP(*(.inv_constants.SW_VERSION_MAJOR))
	  KEEP(*(.inv_constants.SW_VERSION_MINOR))
	  KEEP(*(.inv_constants.MAGIC_NUMBER))
	  KEEP(*(.inv_constants.*));
	  KEEP(*(.inv_constants));
  } >INV_CONST

This works for putting the variables in the output .hex file, but six times each:

:020000040801F1
:100008000000000000000101010101014536271828
:1000180045362718453627184536271845362718F0
:04002800453627181A
:020000040802F0
:1000000000000220B1DA0208F9CE020807CF020888

This can be better seen in STM32CubeIDE's build analyzer:

0690X00000Bw7ycQAB.jpg

I guess the reduplication of the variables in flash is due to padding, but for me it doesn't make sense.

The toolchain I'm using is GNU-Tools for STM32, version 7-2018-q2-update and I'm compiling/linking with g++ (C++ project).

Now comes the problem:

The previous projects were C projects and the same code resulted in 4 times reduplication (now 6 times) of the variables (actually constants) in the custom flash section (by the way, the other variables are placed in flash only once). Thus, the addresses where the other program looks for the constants in flash are no longer valid...

So, my question is, how can I influence the number of reduplication (at best, turn it off)?

Also, if anybody could help me understand why there is this reduplication, I would highly appreciate it (in case of padding I wouldn't understand why there is exactly 6 times reduplication here and why also the longest variable)...

What I tried so far:

  • used ALIGN() instruction in the linker script within and before the custom section with different alignment sizes, but there was no change (neither with 2 nor with 8)
  • inserted ". += 1" to insert some gap manually, but this only added another instance of the variables...

Anybody an idea?

Kind regards,

Markus

1 ACCEPTED SOLUTION

Accepted Solutions
MB_Inv
Associate III

Turned out that updating STM32CubeIDE to version 1.2.1 (Build: 5190_20200115_1224 (UTC); which also uses a new version of the toolchain, I think) and creating a new STM32 C++ project (the new version sets up the project a little bit different when it comes to paths and the linker script), the linker now placed the variables only once for each definition (as I would expect it)...

So, the solution was to update the tools...

Kind regards,

Markus

View solution in original post

2 REPLIES 2
MB_Inv
Associate III

One thing that I already found out is the following:

When declaring the constants in the following way:

__attribute__((section(".inv_constants")))

then the whole pack of constants is reduplicated:

0690X00000Bw7wlQAB.jpg

So, I can use this to have a workaround:

/*
 * Constants which should go to specific locations in flash
 */
/** Firmware major version */
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MAJOR{0};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MAJOR2{0};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MAJOR3{0};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MAJOR4{0};
/** Firmware minor version */
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MINOR{1};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MINOR2{1};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MINOR3{1};
__attribute__((section(".inv_constants"))) \
		static const uint8_t SW_VERSION_MINOR4{1};
/** Magic number for update tool */
__attribute__((section(".inv_constants"))) \
		static const uint32_t MAGIC_NUMBER{0x18273645};
__attribute__((section(".inv_constants"))) \
		static const uint32_t MAGIC_NUMBER2{0x18273645};
__attribute__((section(".inv_constants"))) \
		static const uint32_t MAGIC_NUMBER3{0x18273645};
__attribute__((section(".inv_constants"))) \
		static const uint32_t MAGIC_NUMBER4{0x18273645} ;

gets me to have the same reduplication as for my previous projects (4 times) and some more "waste" of memory space (which is not a big problem in this case).

However, I'd still be interested in a "proper" solution and understanding why the linker behaves like this...

Kind regards,

Markus

MB_Inv
Associate III

Turned out that updating STM32CubeIDE to version 1.2.1 (Build: 5190_20200115_1224 (UTC); which also uses a new version of the toolchain, I think) and creating a new STM32 C++ project (the new version sets up the project a little bit different when it comes to paths and the linker script), the linker now placed the variables only once for each definition (as I would expect it)...

So, the solution was to update the tools...

Kind regards,

Markus