cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CubeIDE - How to set values in DTCM to non zero values using the Linker Script and Startup file.

Garnett.Robert
Senior III

Hi

I have a variable:

 

/* Parameters (default storage) */
struct P_GovTrimControl_T_
{
  real32_T FreqSP;
  real32_T kD;
  real32_T kI;
  real32_T kN;
  real32_T kP;
};
typedef struct P_GovTrimControl_T_ P_GovTrimControl_T;

#define USE_DTCM __attribute__((section (".DTCM_MISC")))

P_GovTrimControl_T  __attribute__((__aligned__(4))) USE_DTCM GovTrimControl_P =
{
  50.0F,
  2.0F,
  20.0F,
  2.0F,
  30.0F
};

The linker script memory allocation:
/* Memories definition */
MEMORY
{
  DTCM_STACK    	(xrw)   : ORIGIN = 0x20000000,   		LENGTH = _Min_Heap_Size + _Min_Stack_Size
  DTCM_MISC	   		(xrw)    : ORIGIN = 0x20002000,   		LENGTH = 120K
  ITCMRAM      		(xrw)    : ORIGIN = 0x00000000,   		LENGTH = 64K
  RAM_D1       		(xrw)    : ORIGIN = 0x24000000,   		LENGTH = 512K
  RAM_D2       		(xrw)    : ORIGIN = 0x30000000,   		LENGTH = 288K
  RAM_D3       		(xrw)    : ORIGIN = 0x38000000,   		LENGTH = 64K
...
}

 

If I use the default allocation of the variable to SRAM1, the values get set to the values assigned in the code as the default linker script and startup do the heavy lifting.  If I set the allocation to the DTCM_RAM they do not get set by the startup assembler code and assume random values.

 

How do I set up the linker script and the startup code to set these values.

 

I know I could set them in my C Code on start up after "main" but I have a lot of these as filter coefficients and would like to make this process all happen in the startup. Maintenance of the code without this will be a nightmare.

 

I don't get how I can map the flash addresses of the variable I want in tha DTCM with the DTCM addresses and then pass these to the startup with an appropriate "fill" loop.

I have read the GCC linker docs, but have been unable to get anything to work.

Has anyone done this or know how to do it?

 

Kind Regards

Rob

1 ACCEPTED SOLUTION

Accepted Solutions

Thankyou TDK,

 

I understand the overall priciples, the problem I had was hoew to I get the copy code to start at the Flash address of the STCM section

I experimented with a small project and found that it can be done thus:

Linker Script:

 

/* Memory section of Linker Script */
MEMORY
{
  DTCM_MISC 	 	(xrw)  	: ORIGIN = 0x20000000, LENGTH = 128K
  FLASH 			(rx)   	: ORIGIN = 0x08000000, LENGTH = 2048K ...

/* Section part of Linker Script */
...
  /* Initialized data sections goes into DTCM RAM, load LMA copy after code */

    /* _si_dtmc points to .DTCM_MISC segment in the flash
    	used by the startup copy loop */
  _si_dtmc = LOADADDR(.DTCM_MISC);

  .DTCM_MISC :
  {
	. = ALIGN(4);
	_sDTCM_MISC = .;
	__sDTCM_MISC__ = _sDTCM_MISC;
	*(.DTCM_MISC) /* All nominated variables */
	. = ALIGN(4);
	_eDTCM_MISC = .;
	__eDTCM_MISC__ = _eDTCM_MISC;
  } >DTCM_MISC AT> FLASH
...

 

It is the _si_dtmc = LOADADDR(.DTCM_MISC); statement that assign the variable _si_dtmc  to that part of the flash that holds the variables allocated to the DTCM.

Startup Code:

 

...
/******** Added Start **********/
/* Start and end of miscellaneous DTCM */
.word  _sDTCM_MISC
.word  _eDTCM_MISC
.word  _si_dtmc
...

  /* Do next segment DTCM Initialised Data*/
  ldr r0, = _sDTCM_MISC		/*set the start addr of the DTCM */
  ldr r1, = _eDTCM_MISC		/*set the end addr of the DTCM */
  ldr r2, = _si_dtmc		/*set the start addr of the FLASH DTCM_MISC section */
  movs r3, #0
  b LoopCopyDTCMInit

CopyDTCMInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyDTCMInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDTCMInit
...

 

 

I tried to attach a tar ball (9.3Mb) of the project to this post, but the computer said NO even though .tar files are supposed to be allowed.

 

Kind Regards

Rob

View solution in original post

2 REPLIES 2
TDK
Guru

You need to both modify the linker script to store the values in flash, and you need to modify the startup code to copy those values from flash into DTCM. Here is where it happens for RAM. You'll need to add another section from DTCM, along with creating those symbols (_sdata, etc, but for DTCM) in the linker script.

TDK_0-1727263573972.png

 

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

Thankyou TDK,

 

I understand the overall priciples, the problem I had was hoew to I get the copy code to start at the Flash address of the STCM section

I experimented with a small project and found that it can be done thus:

Linker Script:

 

/* Memory section of Linker Script */
MEMORY
{
  DTCM_MISC 	 	(xrw)  	: ORIGIN = 0x20000000, LENGTH = 128K
  FLASH 			(rx)   	: ORIGIN = 0x08000000, LENGTH = 2048K ...

/* Section part of Linker Script */
...
  /* Initialized data sections goes into DTCM RAM, load LMA copy after code */

    /* _si_dtmc points to .DTCM_MISC segment in the flash
    	used by the startup copy loop */
  _si_dtmc = LOADADDR(.DTCM_MISC);

  .DTCM_MISC :
  {
	. = ALIGN(4);
	_sDTCM_MISC = .;
	__sDTCM_MISC__ = _sDTCM_MISC;
	*(.DTCM_MISC) /* All nominated variables */
	. = ALIGN(4);
	_eDTCM_MISC = .;
	__eDTCM_MISC__ = _eDTCM_MISC;
  } >DTCM_MISC AT> FLASH
...

 

It is the _si_dtmc = LOADADDR(.DTCM_MISC); statement that assign the variable _si_dtmc  to that part of the flash that holds the variables allocated to the DTCM.

Startup Code:

 

...
/******** Added Start **********/
/* Start and end of miscellaneous DTCM */
.word  _sDTCM_MISC
.word  _eDTCM_MISC
.word  _si_dtmc
...

  /* Do next segment DTCM Initialised Data*/
  ldr r0, = _sDTCM_MISC		/*set the start addr of the DTCM */
  ldr r1, = _eDTCM_MISC		/*set the end addr of the DTCM */
  ldr r2, = _si_dtmc		/*set the start addr of the FLASH DTCM_MISC section */
  movs r3, #0
  b LoopCopyDTCMInit

CopyDTCMInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyDTCMInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDTCMInit
...

 

 

I tried to attach a tar ball (9.3Mb) of the project to this post, but the computer said NO even though .tar files are supposed to be allowed.

 

Kind Regards

Rob