Managed linker scripts are great on one side: the simplify the otherwise complex GNU linker script handling. On the other side it requires knowledge how to tweak them in case ‘non-standard’ behavior is needed.

I described the context in Putting Code of Files into Special Section with the GNU Linker.
This is very useful for example putting code or data into specific memory areas, for example if using position independent code or in the context of libraries and bootloaders.
The question is: how to do this with a managed linker script as in the NXP MCUXpresso IDE?
First, we need a memory section which we can use. I’m using here the NXP LPC55S16 which has one text/FLASH region, so I used the ‘Split’ button to have another section:

The next thing is that I have to specify which code I want to place into this section. There is an ‘extra linker script input section’ I can use:

- Input section description: The text used in the linker script. I can use wildcards (*) and specify the file name(s). After the file name I can specify the section names with wildcards too.
- Region: The region name I have defined
- Section Type: The linker script will be split into different areas like .text or .data. Specify for which section kind it shall be used.
What it does is creating an extra placement in the linker script file like this one:

With this, check the placement in the linker *.map file:

The image below shows the full flow:

With this, I can place code (or data) into specific sections using managed linker scripts.
Happy placing 🙂
just wanted to also point out the magic of “cr_section_macros.h”. You can get nice macros that are compatible with all of the MCUXPresso managed linker scripts. It has been a life saver for me!
LikeLiked by 1 person
Agreed, they are very useful. I’m only wondering why they are not part of the MCUXpresso SDK and why the file is labeled ‘NXP confidential’. I don’t see anything in there which would make it confidential.
LikeLike
That header dates back to Code Red days (hence the “cr” in its filename). Looks like someone decided to change the license inappropriately during 2020 – there is no way the file should be marked NXP Confidential given its been provided to users as part of Red Suite / LPCXpresso IDE / MCUXpresso IDE for well over 10 years!
LikeLiked by 1 person
Thanks Andy!
LikeLike
Pingback: Position-Independent Code with GCC for ARM Cortex-M | MCU on Eclipse
Hallo Erich,
I’m moving a project from kinetis k60 to imxrt 1024 microcontroller because in this period it’s impossible to find k60 microcontrollers.
I’m using MCUXpresso 11.5.0_7232.
In this project there is a file…its name is pictures.c. In this file there are only many const arrays. When I developed this project with K60, to place all these arrays in FLASH memory I used this preprocessor command:
#pragma define_section FlashConst “.FlashConst”, abs32 ,R
#pragma section FlashConst begin
I tried what you explained above to place a file in FLASH, but my arrays are in RAM again. I’d like avoing to place the prefix “const” for each array. The procedure that you described works for a file where there are only const arrays?
Do you think that I wrong somethig or there is another fast way to place the whole file in FLASH?
Many thaks in advance for your support.
Kinds Regards,
Stefano
LikeLiked by 1 person
Hi Stefano,
could you check your linker (.ld) file where it places your “.FlashConst” section?
LikeLike
Hi Erich,
in my linker file (Debug.ld) I have (I delate some raws because is too long to post):
.text : ALIGN(4)
{
FILL(0xff)
__vectors_start__ = ABSOLUTE(.) ;
KEEP(*(.isr_vector))
/* Global Section Table */
. = ALIGN(4) ;
__section_table_start = .;
__data_section_table = .;
KEEP(*(.DatiBoot))
*(.text*)
*/pictures.o(.text .text*)
*(.rodata .rodata.* .constdata .constdata.*)
. = ALIGN(4);
} > BOARD_FLASH
and in the Debug_memory.ld I have:
MEMORY
{
/* Define each memory region */
BOARD_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x400000 /* 4M bytes (alias Flash) */
SRAM_DTC (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 /* 192K bytes (alias RAM) */
SRAM_ITC (rwx) : ORIGIN = 0x0, LENGTH = 0x0 /* 0M bytes (alias RAM2) */
SRAM_OC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x10000 /* 64K bytes (alias RAM3) */
BOARD_SDRAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x1e00000 /* 30M bytes (alias RAM4) */
NCACHE_REGION (rwx) : ORIGIN = 0x81e00000, LENGTH = 0x200000 /* 2M bytes (alias RAM5) */
}
In the “Managed linker script” I wrote in “input section description” : */pictures.o(.text .text*), in “Region”: “BOARD_FLASH” and in “section type”: “.rodata”.
I hope this is helpful
Kinds Regards,
Stefano
LikeLiked by 1 person
can you check the .map file? maybe it shows why it is not placed in the expected region?
LikeLike
Hi Erich,
The pictures.c file is not in the Source directory, but in a its subdirectory. Do you think that it could be a problem?
In the map file I have this:
*/pictures.o(SORT_BY_ALIGNMENT(.text) SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata) SORT_BY_ALIGNMENT(.rodata.*) SORT_BY_ALIGNMENT(.constdata) SORT_BY_ALIGNMENT(.constdata.*))
*fill* 0x6006a74a 0x2 ff
It is in FLASH.
Anyway all the arrays of the pictures.c file are placed in RAM. For example one of them is
.data.btnPiu 0x20005e88 0x34e ./source/D4D_screen/pictures.o
0x20005e88 btnPiu
*fill* 0x200061d6 0x2 ff
Many thanks for your support.
Kinds Regards,
Stefano
LikeLiked by 1 person
Yes, the sub-folder might be the problem, as the filter is not taking the file into consideration.
Maybe the examples at https://mcuoneclipse.com/2021/05/26/placing-code-in-sections-with-managed-gnu-linker-scripts/ can help?
LikeLike