Hi,
Hello,
I use S32K144 with S32DS 2018.R1.
How can I locate the memcpy function from in the RAM, that this function ist executed from RAM.
My linker file:
*(EXCLUDE_FILE(lib_a-memcpy-stub.o) .text)
…..
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
*libc_nano.a:lib_a-memcpy-stub.o (.text).
But it doesn't work.
In my map file memcpy is locatet in rom
Solved! Go to Solution.
Hello Lutz,
Thanks for this interesting question.
I'd suggest you to adjust your ld file:
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
/* Exclude file(s) from NewLib libc.a from .text.* section */
*(EXCLUDE_FILE (*libc.a:lib_a-memcpy-stub.o) .text*)
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
2. Adjust the rule that places a memcpy object file into Code RAM section. Please be aware that the compiler option -ffunction-section was used to generate the libraries and it creates a special section for each function (e.g. memcpy is placed into .text.memcpy input section). Therefore your rule has to be adjusted. (see also how to allocate an input section from library file to a custom output section? )
*libc.a:lib_a-memcpy-stub.o (.text*)
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
*libc.a:lib_a-memcpy-stub.o (.text*) /* add memcpy from the NewLib library here*/
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
__code_ram_end__ = .;
} > m_data
Now If you build the project and check the map file you should see memcpy is placed into custom .code_ram section in memory:
.code 0x1fff881c 0x18 load address 0x00000d90
0x1fff881c . = ALIGN (0x4)
0x1fff881c __CODE_RAM = .
0x1fff881c __code_start__ = .
0x1fff881c __code_ram_start__ = .
*(.code_ram)
*libc.a:lib_a-memcpy-stub.o(.text*)
.text.memcpy 0x1fff881c 0x16 C:/NXP/S32DS_ARM_v2018.R1/Cross_Tools/gcc-6.3-arm32-eabi/arm-none-eabi/newlib/lib/thumb/v7e-m\libc.a(lib_a-memcpy-stub.o)
0x1fff881c memcpy
0x1fff8834 . = ALIGN (0x4)
*fill* 0x1fff8832 0x2
0x1fff8834 __code_end__ = .
0x1fff8834 __code_ram_end__ = .
0x00000da8 __CODE_END = (__CODE_ROM + (__code_end__ - __code_start__))
0x00000da8 __CUSTOM_ROM = __CODE_END
Please be aware that if you are placing a function into RAM (e.g. to improve speed performance) make sure you are adding also sub-functions called by that function (typically located in a different object file) otherwise the performance gain may not be as high as expected.
I've noticed I used NewLib instead of NewLib nano in the example. Anyway the approach is the same regardless of specific library used.
Hope it helps.
Stan
Hello Lutz,
Thanks for this interesting question.
I'd suggest you to adjust your ld file:
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
/* Exclude file(s) from NewLib libc.a from .text.* section */
*(EXCLUDE_FILE (*libc.a:lib_a-memcpy-stub.o) .text*)
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
2. Adjust the rule that places a memcpy object file into Code RAM section. Please be aware that the compiler option -ffunction-section was used to generate the libraries and it creates a special section for each function (e.g. memcpy is placed into .text.memcpy input section). Therefore your rule has to be adjusted. (see also how to allocate an input section from library file to a custom output section? )
*libc.a:lib_a-memcpy-stub.o (.text*)
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
*libc.a:lib_a-memcpy-stub.o (.text*) /* add memcpy from the NewLib library here*/
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
__code_ram_end__ = .;
} > m_data
Now If you build the project and check the map file you should see memcpy is placed into custom .code_ram section in memory:
.code 0x1fff881c 0x18 load address 0x00000d90
0x1fff881c . = ALIGN (0x4)
0x1fff881c __CODE_RAM = .
0x1fff881c __code_start__ = .
0x1fff881c __code_ram_start__ = .
*(.code_ram)
*libc.a:lib_a-memcpy-stub.o(.text*)
.text.memcpy 0x1fff881c 0x16 C:/NXP/S32DS_ARM_v2018.R1/Cross_Tools/gcc-6.3-arm32-eabi/arm-none-eabi/newlib/lib/thumb/v7e-m\libc.a(lib_a-memcpy-stub.o)
0x1fff881c memcpy
0x1fff8834 . = ALIGN (0x4)
*fill* 0x1fff8832 0x2
0x1fff8834 __code_end__ = .
0x1fff8834 __code_ram_end__ = .
0x00000da8 __CODE_END = (__CODE_ROM + (__code_end__ - __code_start__))
0x00000da8 __CUSTOM_ROM = __CODE_END
Please be aware that if you are placing a function into RAM (e.g. to improve speed performance) make sure you are adding also sub-functions called by that function (typically located in a different object file) otherwise the performance gain may not be as high as expected.
I've noticed I used NewLib instead of NewLib nano in the example. Anyway the approach is the same regardless of specific library used.
Hope it helps.
Stan
Hello Stan,
it doesn't work to locate the memcpy into the ram.
I tested it with functions from S32K14xMMCLIB. It works fine. But with memcpy it doesnt work.
In the mapfile I have this entries:
.text.memcpy 0x00017648 0x16
.text.memcpy 0x00017648 0x16 C:/NXP/S32DS_ARM_v2018.R1/Cross_Tools/gcc-6.3-arm32-eabi/arm-none-eabi/newlib/lib/thumb/v7e-m/fpv4-sp/hard\libc.a(lib_a-memcpy-stub.o)
0x00017648 memcpy
*S32K14x_AMMCLIB.a:GDFLIB_FilterMA_c.o(.text)
.text 0x1fffaf08 0x11c C:/NXP/S32DS_ARM_v2018.R1/S32DS/S32K14x_AMMCLIB_v1.1.15/lib/s32ds_arm32/S32K14x_AMMCLIB.a(GDFLIB_FilterMA_c.o)
0x1fffaf08 GDFLIB_FilterMAInit_F32
0x1fffaf10 GDFLIB_FilterMASetState_F32
0x1fffaf50 GDFLIB_FilterMA_F32
0x1fffaf88 GDFLIB_FilterMAInit_F16
0x1fffaf90 GDFLIB_FilterMASetState_F16
0x1fffafd4 GDFLIB_FilterMA_F16
0x1fffafec GDFLIB_FilterMAInit_FLT
0x1fffaff4 GDFLIB_FilterMASetState_FLT
0x1fffb004 GDFLIB_FilterMA_FLT
fill 0x1fffb024 0x4
.text.__stub 0x1fffb028 0x118 linker stubs
*S32K14x_AMMCLIB.a:GFLIB_Sqrt_c.o(.text)
*libc.a:lib_a-memcpy-stub.o(.text)
0x1fffb140 . = ALIGN (0x4)
0x1fffb140 __code_end__ = .
0x1fffb140 __code_ram_end__ = .
0x0001a3a8 __CODE_END = (__CODE_ROM + (__code_end__ - __code_start__))
0x0001a3a8 __CUSTOM_ROM = __CODE_END
When I debug, the memcpy code on 0x00017648 is ececued.
BR Lutz
Von: stanish
Gesendet: Donnerstag, 14. März 2019 15:49
An: Köhler, Lutz <lutz.koehler@acd-antriebstechnik.de>
Betreff: Re: - Re: How can I locate the memcpy funktion in RAM ?
NXP Community <https://community.freescale.com/resources/statics/1000/35400-NXP-Community-Email-banner-600x75.jpg>
Re: How can I locate the memcpy funktion in RAM ?
reply from Stanislav Sliva<https://community.nxp.com/people/stanish?et=watches.email.thread> in S32 Design Studio - View the full discussion<https://community.nxp.com/message/1125081?commentID=1125081&et=watches.email.thread#comment-1125081>
Hi Lutz,
If you are linking NewLib Nano you should adjust the library name to "libc_nano".
See below the example with two object files - memcpy, memset from Newlib Nano:
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
/* Exclude file(s) from NewLib libc.a from .text.* section */
*(EXCLUDE_FILE (*libc_nano.a:lib_a-memcpy-stub.o *libc_nano.a:lib_a-memset.o) .text*)
...
.code : AT(__CODE_ROM)
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
__code_ram_start__ = .;
*(.code_ram) /* Custom section for storing code in RAM */
. = ALIGN(4);
*libc_nano.a:lib_a-memcpy-stub.o (.text*) /* add memcpy from the NewLib-nano library here*/
*libc_nano.a:lib_a-memset.o (.text*) /* add memset from the NewLib-nano library here*/
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
__code_ram_end__ = .;
} > m_data
after build I can see this in .map file:
.code 0x1ffe0464 0x28 load address 0x00000844
0x1ffe0464 . = ALIGN (0x4)
0x1ffe0464 __CODE_RAM = .
0x1ffe0464 __code_start__ = .
0x1ffe0464 __code_ram_start__ = .
*(.code_ram)
0x1ffe0464 . = ALIGN (0x4)
*libc_nano.a:lib_a-memcpy-stub.o(.text*)
.text.memcpy 0x1ffe0464 0x16 C:/NXP/S32DS_ARM_v2018.R1/Cross_Tools/gcc-6.3-arm32-eabi/arm-none-eabi/newlib/lib/thumb/v7e-m\libc_nano.a(lib_a-memcpy-stub.o)
0x1ffe0464 memcpy
*libc_nano.a:lib_a-memset.o(.text*)
.text.memset 0x1ffe047a 0x10 C:/NXP/S32DS_ARM_v2018.R1/Cross_Tools/gcc-6.3-arm32-eabi/arm-none-eabi/newlib/lib/thumb/v7e-m\libc_nano.a(lib_a-memset.o)
0x1ffe047a memset
0x1ffe048c . = ALIGN (0x4)
*fill* 0x1ffe048a 0x2
0x1ffe048c __code_end__ = .
0x1ffe048c __code_ram_end__ = .
0x0000086c __CODE_END = (__CODE_ROM + (__code_end__ - __code_start__))
0x0000086c __CUSTOM_ROM = __CODE_END
Hope this solves the problem.
Stan
Hello Stan,
I tested it with libc and libc_nano. But in both cases I have the same behavior. The memcpy isn’t located in the RAM.
I don’t understand why. With the S32K14xMMCLIB works it.
Dependents it from the project settings ?
Lutz
Von: stanish
Gesendet: Montag, 18. März 2019 10:31
An: Köhler, Lutz <lutz.koehler@acd-antriebstechnik.de>
Betreff: Re: - Re: How can I locate the memcpy funktion in RAM ?
NXP Community <https://community.freescale.com/resources/statics/1000/35400-NXP-Community-Email-banner-600x75.jpg>
Re: How can I locate the memcpy funktion in RAM ?
reply from Stanislav Sliva<https://community.nxp.com/people/stanish?et=watches.email.thread> in S32 Design Studio - View the full discussion<https://community.nxp.com/message/1126015?commentID=1126015&et=watches.email.thread#comment-1126015>
Lutz,
I suspect you are linking with a different lib selected.
The linker script file must match with the project settings:
Please make sure you are using newlib_nano library in Target Processor settings + you refers to newlib_nano in .ld file.
Attached is an example project that I used.
Regards,
Stan