Hi,
We are using S32K314 part in one of our products. Based on the data sheet, this device comes with 128KB of DTCM memory, which is splitted into DTCM-0 and DTCM-1, each of 64KB. However in the linker script, i can see only 64KB of DTCM-0 memory being mapped. Also, i am able to allocate data elements from DTCM-0 using the following attribute.
__attribute__ ((section(".dtcm0_data")))
The following are my questions.
1. How can i create a new entry for DTCM-1 in my linker script ?
2. What compiler attribute can i use to allocate memory from DTCM-1 ?
The following is a summary of my existing linker script. The full linker script is also attached.
I will really appreciate if someone can help me here.
Regards, Biju
Summary of my existing linker script
------------------------------------
MEMORY
{
int_flash : ORIGIN = 0x00400000, LENGTH = 0x003D4000 /* 4096K - 176K (sBAF + HSE)*/
int_itcm : ORIGIN = 0x00000000, LENGTH = 0x00008000 /* 32K */
int_dtcm : ORIGIN = 0x20000000, LENGTH = 0x00010000 /* 64K */
int_sram : ORIGIN = 0x20400000, LENGTH = 0x0002DF00 /* 183.9K */
int_sram_fls_rsv : ORIGIN = 0x2042DF00, LENGTH = 0x00000100 /* 0.1K */
int_sram_stack_c0 : ORIGIN = 0x2042E000, LENGTH = 0x00001000 /* 4KB */
int_sram_stack_c1 : ORIGIN = 0x2042F000, LENGTH = 0x00001000 /* 4KB */
int_sram_no_cacheable : ORIGIN = 0x20430000, LENGTH = 0x0000FF00 /* 64KB, needs to include int_results */
int_sram_results : ORIGIN = 0x2043FF00, LENGTH = 0x00000100
int_sram_shareable : ORIGIN = 0x20440000, LENGTH = 0x00004000 /* 16KB */
ram_rsvd2 : ORIGIN = 0x20444000, LENGTH = 0 /* End of SRAM */
}
已解决! 转到解答。
Hi @biju_nair,
Sorry for the delay, I was out of office for a few days.
init_table is an array used to initialize global variables.
zero_table is an array is for uninitialized global variables so that they can have defined 0 value.
Hi Daniel,
Thanks much for sharing a sample code. I have tested your code and it works perfectly.
However, i see that in the linker script that you have shared, i don't see a region for dtcm0 region. So i have added the following line in the code and tried to build it.
uint32_t __attribute__ ((section(".dtcm0_data"))) dtcm0_data_array[1 * 1024];
I got the following error.
c:/nxp/s32ds.3.5/s32ds/build_tools/gcc_v10.2/gcc-10.2-arm32-eabi/bin/../lib/gcc/arm-none-eabi/10.2.0/../../../../arm-none-eabi/bin/real-ld.exe: section .dtcm0_data LMA [00405d48,00406d47] overlaps section .dtcm1_bd_data LMA [00405d48,00415d47]
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:39: Example_S32K314_DTCM1_Backdoor_RTD201_DS34_v1.elf] Error 1
"make -j4 all" terminated with exit code 2. Build might be incomplete.
The following are the contents of the map file.
.dtcm0_data 0x2043040c 0x1000 load address 0x00405d48
.dtcm0_data 0x2043040c 0x1000 ./src/main.o
0x2043040c dtcm0_data_array
.dtcm1_bd_data 0x21400000 0x10000 load address 0x00405d48
0x21400000 . = ALIGN (0x4)
0x21400000 __dtcm1_bd_data_start__ = .
So i have made some cosmetic changes to the linker script (which is attached here) and now i see that this seems to be working. So can you kindly help me understand the following queries.
1. I see that in the system.c file, we are setting rbar[7] and rasr[7] registers with the new DTCM1 region. But we have commented out the RAM_SHAREABLE_START here. Will this not create an issue ?
2. when i integrate this linker script into my code, i see a memory exception when i try to access this location. The following is the contents of my init_table in startup_cm7.s file. Am i missing something here ? I am using the linker script, which i have already attached now.
.section ".init_table", "a"
.long 4
.long __RAM_CACHEABLE_START
.long __ROM_CACHEABLE_START
.long __ROM_CACHEABLE_END
.long __RAM_NO_CACHEABLE_START
.long __ROM_NO_CACHEABLE_START
.long __ROM_NO_CACHEABLE_END
.long __RAM_SHAREABLE_START
.long __ROM_SHAREABLE_START
.long __ROM_SHAREABLE_END
.long __RAM_INTERRUPT_START
.long __ROM_INTERRUPT_START
.long __ROM_INTERRUPT_END
.long __RAM_DTCM0_DATA_START
.long __ROM_DTCM0_DATA_START
.long __ROM_DTCM0_DATA_END
.long __RAM_DTCM1_BD_DATA_START
.long __ROM_DTCM1_BD_DATA_START
.long __ROM_DTCM1_BD_DATA_END
3. With S32DS, how can i access the MMFSR register and other registers ? I am using a PE-Micro debugger.
Hello @biju_nair,
1.
Yes, I modified the default linker that does not utilize DTCM0.
2.
Yes, it can create issues, it was just a quick test project to show how it works, not a complete solution.
3.
There are some core registers but not all of them:
Regards,
Daniel
Hi Daniel,
Thanks much for the super fast response.
One more doubt.
1. Is it theoretically possible to use both dtcm0 and dtcm1 at the same time ?
2. I see that we can only have 8 entries if MPU is enabled. As i am not going to use ITCM region, can i use that index in MPU table for DTCM1 ?
Regards, Biju
Hi @biju_nair,
Sorry for the delay, I was out of office for a few days.
init_table is an array used to initialize global variables.
zero_table is an array is for uninitialized global variables so that they can have defined 0 value.
Hello @biju_nair,
The CM7_0 can access the DTCM_1 through backdoor only.
1. Add the DTCM1 section in the linker file:
int_dtcm_1_bd : ORIGIN = 0x21400000, LENGTH = 0x00010000 /* 64K */
__dtcm1_bd_data_rom = __shareable_data_rom_end;
.dtcm1_bd_data : AT(__dtcm1_bd_data_rom)
{
. = ALIGN(4);
__dtcm1_bd_data_start__ = .;
KEEP(*(.dtcm1_bd_data))
. = ALIGN(4);
__dtcm1_bd_data_end__ = .;
} > int_dtcm_1_bd
__dtcm1_bd_data_rom_end = __dtcm1_bd_data_rom + (__dtcm1_bd_data_end__ - __dtcm1_bd_data_start__);
__INT_DTCM_1_BD_START = ORIGIN(int_dtcm_1_bd);
__INT_DTCM_1_BD_END = ORIGIN(int_dtcm_1_bd) + LENGTH(int_dtcm_1_bd);
__RAM_DTCM1_BD_DATA_START = __dtcm1_bd_data_start__;
__ROM_DTCM1_BD_DATA_START = __dtcm1_bd_data_rom;
__ROM_DTCM1_BD_DATA_END = __dtcm1_bd_data_rom_end;
__DTCM1_BD_START = ORIGIN(int_dtcm_1_bd);
__DTCM1_BD_SIZE = 0x10; /*64 kbyte*/
2. Initialize DTCM1 ECC in startup_cm7.s:
DTCM1_BD_Init:
/* Initialize DTCM1_BD ECC */
ldr r0, =__DTCM1_BD_INIT
cmp r0, 0
/* Skip if __DTCM_INIT is not set */
beq DTCM1_BD_LOOP_END
/* Enable TCM */
LDR r1, =CM7_DTCMCR
LDR r0, [r1]
LDR r2, =0x1
ORR r0, r2
STR r0, [r1]
ldr r1, =__INT_DTCM_1_BD_START
ldr r2, =__INT_DTCM_1_BD_END
subs r2, r1
subs r2, #1
ble DTCM1_BD_LOOP_END
movs r0, 0
movs r3, 0
DTCM1_BD_LOOP:
stm r1!, {r0,r3}
subs r2, #8
bge DTCM1_BD_LOOP
nop
DTCM1_BD_LOOP_END:
3. If the MPU is enabled, the memory must be added in system.c:
extern uint32 __DTCM1_BD_START[];
extern uint32 __DTCM1_BD_SIZE[];
/*DTCM1_BD section*/
rbar[7]=(uint32)__DTCM1_BD_START;
rasr[7]=((uint32)0x030B0001UL)|(((uint32)__DTCM1_BD_SIZE - 1) << 1);
Please find the project attached,
Regrads,
Daniel
Hello Mr. @danielmartynek,
I am working on S32K311 MCU, trying to access DTCM0 memory using eDMA, but eDMA data is not updating on DTCM0 memory location. also tried to access through DTCM0 backdoor. after initializing of DTCM0 using eDMA but unfortunately not succeed.
Can you please provide the example code for access DCTM0 using eDMA , it will be very helpful in our development.?
Hi @raj12,
Please create a thread for any eDMA questions.
DTCM can be accessed by the eDMA via the backdoor only.
I'm afraid we don't have such example at the moment.
Regards,
Daniel