How to use DTCM-1 memory in S32K314 controllers

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

How to use DTCM-1 memory in S32K314 controllers

Jump to solution
2,482 Views
biju_nair
Contributor III

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 */
}

0 Kudos
1 Solution
1,934 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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. 

 

View solution in original post

12 Replies
2,349 Views
biju_nair
Contributor III

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.

0 Kudos
2,343 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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:

danielmartynek_0-1686318247686.png

 

Regards,

Daniel

 

0 Kudos
2,333 Views
biju_nair
Contributor III

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

0 Kudos
2,324 Views
danielmartynek
NXP TechSupport
NXP TechSupport

1. Yes, the CM7_0 can access DTCM0 directly and DTCM1 via the backdoor access.

2. There are 16 MPU descriptors, it is up to you.

You can use the RTD driver for it.

danielmartynek_0-1686319559932.png

 

BR, Daniel

0 Kudos
2,038 Views
biju_nair
Contributor III

Hi Daniel,

Did you used S32KDS 3.4 or 3.5 for this ? Also what was the version of RTD drivers that you used for this project ?

Regards, Biju

0 Kudos
2,019 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Biju,

S32DS 3.4, RTD RTM 2.0.1.

 

 

 

 

0 Kudos
2,007 Views
biju_nair
Contributor III

Hi Daniel,

One more clarification.

I see that in the startup code, there is a init_table and zero_table that is defined. Why exactly is this required ?

Regards, Biju

0 Kudos
1,935 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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. 

 

1,912 Views
biju_nair
Contributor III

Thanks a lot Daniel. Appreciate your help.

Regards, Biju

Tags (1)
0 Kudos
2,377 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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

 

0 Kudos
321 Views
raj12
Contributor III

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.?

0 Kudos
313 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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

0 Kudos