Prevent .data init-copy when executing from SRAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Prevent .data init-copy when executing from SRAM

Jump to solution
638 Views
stefano-quantic
Contributor III

I'm running code from SRAM. Specifically, I'm talking about the CM4 core in iMXRT1176; CM7 copies all CM4-related data from Flash to SRAM, and then CM4 can start executing.
CM4 is set to run from RAM since under "Project properties | C/C++ Build | Settings | Tool Settings | MCU C++ Linker | Managed Linker Script" the setting "Link application to RAM" is checked.
However, the .data variables are allocated in a portion of SRAM, while their initializers (copied by the ResetISR by using __data_section_table, etc.) are placed in a different portion of SRAM.
This copy is useless, the global data could just start as already initialized, and the code could immediately use the global variables without doing the initialization explicitly.
It's not about saving the time to do the copy, as much as it is about halving the SRAM occupation due to (non-zero-initialized) global variables.

How can I set the linker to merge the .data section(s) with its initializer section(s), and remove the relevant entry in the initialization table?

0 Kudos
1 Solution
513 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

By default, MCUXpresso IDE projects use a managed linker script mechanism that automatically generates a linker script file without user intervention. This approach is helpful for most of the users but there are some specific scenarios where you would want to use a custom one.

I do not think that the managed linker script could be customizable at that level you would need to modify it according to your needs from the generated one.

Best regards,
Omar

View solution in original post

0 Kudos
3 Replies
583 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

Hello
I hope you are well.

I'm not understanding what you are trying to do with the linker, could you please detail this?

If you want to prevent that data already in RAM is not copied again during startup then you might need to create new tags in the linker so that specific region is not placed on a region that will be copied during startup.

Best regards,
Omar

0 Kudos
576 Views
stefano-quantic
Contributor III

CM4 has two SRAM regions: ITCM [0x1FFE0000, 0x20000000), and DTCM [0x20000000, 0x20020000).
I want to put global data inside the DTCM region, while keeping the code in ITCM (so, ITCM must still be the default region, i.e. the first one specified in the MCUXpresso project properties).
To do this, I set the option "Project | Properties | C/C++ Build | Settings | Tool Settings | MCU C++ Linker | Manged Linker Script | Global data placement" to DTCM RAM instead of "default".

When I choose "default" (which means default to ITCM), the generated linker script specifies sections of this type:
.data {} > ITCM AT> ITCM
Which is correct in placing both the variables and their initializers in ITCM (effectively at the same address).
In this case, the __data_section_table entry for .data is still generated (which is useless, but also mostly harmless):
LONG(LOADADDR(.data));
LONG( ADDR(.data));
LONG( SIZEOF(.data));

Instead, when I set the data placement to DTCM, the generated linker script specifies sections of this type:
.data {} > DTCM AT> ITCM
Which uses space in ITCM for the initializers, and also space in DTCM for the variables.
This would be ok if it was flash instead of ITCM, since in that case it would be necessary to keep the initializers in non-volatile memory. However, here, CM4's SRAM is initialized by CM7 (from flash), so we could skip ITCM altogether. Now we have: initializers are in flash, CM7 copies them to CM4 ITCM, CM4 copies them to CM4 DTCM. What should happen, instead, is: initializers are in flash, CM7 copies them to CM4 DTCM, CM4 does nothing at all (or, at most, it does a DTCM-to-DTCM copy, that is, it copies the variables over themselves, which is just a no-op).

The linker should know that skipping ITCM is possible, since I have set the option: "Project | Properties | C/C++ Build | Settings | Tool Settings | MCU C++ Linker | Manged Linker Script | Link application to RAM".
So, the linker could generate sections of the type:
.data {} > DTCM AT> DTCM
but *not* generate the table entry:
LONG(LOADADDR(.data));
LONG( ADDR(.data));
LONG( SIZEOF(.data));

However, it seems that the "link to RAM" options has absolutely no effect on the generated linker script, nor on any of the build output files.

Is my reasoning correct, so that it could work the way I want it to, if I use a custom linker script and declare .data {} > DTCM AT> DTCM ? It seems to be working, from some testing.
Could the managed linker script do it itself?

0 Kudos
514 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

By default, MCUXpresso IDE projects use a managed linker script mechanism that automatically generates a linker script file without user intervention. This approach is helpful for most of the users but there are some specific scenarios where you would want to use a custom one.

I do not think that the managed linker script could be customizable at that level you would need to modify it according to your needs from the generated one.

Best regards,
Omar

0 Kudos