Skip to main content
Associate
August 5, 2025
Question

HardFault when trying to access more than 128K DTCM on STM32N6 Nucleo Board.

  • August 5, 2025
  • 5 replies
  • 305 views

Hello,

I am trying to extend DTCM to 256K. I followed FLEXMEM Configurations example but I get HardFault as soon as I try to access DTCM in 0x30020000 - 0x30040000 address range. 

Could someone please provide working example of how to extend DTCM to 256K?

5 replies

Tesla DeLorean
Guru
August 5, 2025

"The FLEXMEM configuration depends upon CFGDTCMSZ[3:0] and CFGITCMSZ[3:0] in SYSCFG_CM55TCMCR. It configuration cannot be changed at runtime, a reboot is needed."

https://developer.arm.com/documentation/101051/0101/Signal-descriptions/Static-configuration-signals

https://github.com/STMicroelectronics/STM32CubeN6/blob/main/Projects/NUCLEO-N657X0-Q/Examples/SYSCFG/FLEXMEM_Configurations/README.md?plain=1

https://github.com/STMicroelectronics/STM32CubeN6/blob/main/Projects/NUCLEO-N657X0-Q/Examples/SYSCFG/FLEXMEM_Configurations/FSBL/Src/main.c#L100

The POWER-ON reset might be a challenge from the debugger.

Would suggest doing without it, perhaps instrument HardFault Handler via the USART, and have success/failure indicated by LEDs, so you can observe if it faults, or that it completed the access tests.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
RomainR.
ST Employee
August 5, 2025

Hello @IO1 

This discussion should help you. See the link below. 

https://community.st.com/t5/stm32-mcus-products/stm32n6-hard-fault-when-accessing-tcm/td-p/757557

Best regards,

Romain

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
IO1Author
Associate
August 6, 2025

From FLEXMEM example. How is this code supposed to work? Am I missing something here?

Writing to DTCM_ADDRESS_BASE location DTCM_SIZE_WORD times. How would that prove 

that addresses other that  0x30000000 are accessible?

 

#define DTCM_ADDRESS_BASE 0x30000000
/* DTCM size in words : 256KB / 4 bytes per word */
#define DTCM_SIZE_WORD (256*1024 / 4 )

 

/* Show that memory access to DTCM is extended beyond the default 128KB */
for(int i = 0; i < DTCM_SIZE_WORD; i++)
{
uint32_t * dtcm_ptr = (uint32_t *) DTCM_ADDRESS_BASE;
*dtcm_ptr = 0xa5a5a5a5;
}

 

 
Thank you for your reply. I followed the discussion you posted and was able to use DTCM in the range of 0x30000000 to 0x30020000.
 
 However the attempt to  access the extended 0x30020000 - 0x30040000 region fails. Is there any additional FLEXMEM configuration needed? MPU? I use secure access. Again could you please confirm that I need to powercycle as there is no mention of it in the example.  

 

Associate II
August 1, 2026

Hello all,

this thread seems a bit inactive, but I did not find a clue elsewhere.

I’m trying to use each TCM enlarged to 256KB.

I understand that, after power on, CM55TCMCR has to be modified with SYSCFG_DTCM_256K | SYSCFG_ITCM_256K, and a power on reset has to be triggered.

I also understand that the contents of the TCMs have to be initialized to reset the ECC bits.

 

My status is:

  • My FSBL code works when used loaded into RAM by gdb. I simply start a new gdb session when the FSBL has triggered the POR. In the newly started FSBL gdb session I can use 256K TCMs.
  • This FSBL does not work when started by the Boot ROM. Nothing visible happens.
  • When I just configure the FSBL to use e.g. AXISRAM1 instead of the TCMs, and comment out the power on reset, the FSBL runs fine also when started by the Boot ROM.

 

My questions are:

Is there an example from Real Life (TM) that explains what really needs to be configured before triggering the power on reset?

Has anyone ever *used* larger TCMs. I would not count the FLEXMEM example quoted above as real code.

 

Many thanks and kind regards,

Titus

  

 

 

Associate II
August 2, 2026

As it often happens when the solution is already hidden in the answer.

Of course my reset trigger was not working properly. Sigh.

In case someone else has problems using larger TCMs, stumbles over this post and enjoys using assembler: Attached is a code snippet to grow the DTCM and ITCM of the STM32N6 to 256KB.

#
# Snippet to resize I/D-TCM of the STM32N6 to 256K each
#

# obtain xTCM start+end addresses from linker script
.extern _itcmstart
.extern _itcmextend
.extern _dtcmstart
.extern _dtcmextend
# or define here:
# .equ _itcmstart, 0x10000000
# .equ _itcmextend, 0x10040000
# .equ _dtcmstart, 0x30000000
# .equ _dtcmextend, 0x30040000

.equ CM55TCMCR, 0x56008008 /* SYSCFG->CM55TCMCR */
.equ CM55TCMCR_TCM_MSK, 0xff
.equ CM55TCMCR_DTCM_256K, 0x90
.equ CM55TCMCR_ITCM_256K, 0x09
.equ CM55TCMCR_xTCM_256K, (CM55TCMCR_DTCM_256K | CM55TCMCR_ITCM_256K)
.equ CM55TCMCR_DTCMWSDISABLE, 0x01000000
.equ CM55TCMCR_ITCMWSDISABLE, 0x00800000
.equ CM55TCMCR_xTCMWSDISABLE, (CM55TCMCR_DTCMWSDISABLE | CM55TCMCR_ITCMWSDISABLE)

.equ CM55RSTCR, 0x56008018 /* SYSCFG->CM55RSTCR */
.equ CM55RSTCR_CORE_RESET_TYPE, 0x1

.equ AIRCR, 0xe000ed0c /* SCB->AIRCR */
.equ AIRCR_PRIGROUP_MSK, 0x700
.equ AIRCR_SYSRESETREQ, 0x4
.equ AIRCR_VECTKEY, 0x05fa0000

# for use in YourResetHandler
resize_tcms: /* TCMs vergrößern */
movw r0, #:lower16:CM55TCMCR
movt r0, #:upper16:CM55TCMCR
movw r3, #CM55TCMCR_xTCM_256K
ldr r1, [r0]
and r2, r1, r3
eor r2, r2, r3
movt r3, #:upper16:CM55TCMCR_xTCMWSDISABLE
bic r4, r1, #CM55TCMCR_TCM_MSK
orr r4, r4, r3 /* Größe setzen, ohne Warten */
str r4, [r0]
cbz r2, .Ltcm_already_large /* TCMs sind schon passend groß */
b dopoweronreset

.Ltcm_already_large:
movw r1, #:lower16:_dtcmextend
movt r1, #:upper16:_dtcmextend
movw r5, #:lower16:_itcmextend
movt r5, #:upper16:_itcmextend

/* DTCM löschen */
movw r2, #0
movw r4, #4
movw r0, #:lower16:_dtcmstart
movt r0, #:upper16:_dtcmstart
.Lclear_dtcm:
str r2, [r0]
add r0, r4
cmp r0, r1
bcc .Lclear_dtcm

/* ITCM löschen */
movw r0, #:lower16:_itcmstart
movt r0, #:upper16:_itcmstart
.Lclear_itcm:
str r2, [r0]
add r0, r4
cmp r0, r5
bcc .Lclear_itcm

# ... continue reset handler and enjoy 2*256KB xTCM
bl main

dopoweronreset:
movw r1, #:lower16:CM55RSTCR
movt r1, #:upper16:CM55RSTCR
ldr r0, [r1]
orr r0, r0, #CM55RSTCR_CORE_RESET_TYPE /* Generate Power On Reset */
str r0, [r1]

movw r0, #:lower16:AIRCR
movt r0, #:upper16:AIRCR
ldr r1, [r0]
and r1, r1, #AIRCR_PRIGROUP_MSK /* PRIGROUP-Bits behalten */
movw r2, #AIRCR_SYSRESETREQ /* SYSRESETREQ */
movt r2, #:upper16:AIRCR_VECTKEY /* VECTKEY: Schlüssel, um Schreiben ins AIRCR zu enablieren */
orrs r1, r2 /* Bisherige PRIGROUP-Bits */
dsb sy
str r1, [r0] /* Reset auslösen */
dsb sy
.Lwaitreset:
nop
b .Lwaitreset