cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 Hard_Fault when accessing TCM

filipxsikora
Associate II

Hello,

I have a problem with STM32N6. When trying to access any TCM (ITCM/DTCM) the CPU immediately crashes to the Hard_Fault. Do the TCM memories need to be explicitly enabled or something? From my experience from STM32H7, it was never needed. I've looked around RM for N6 but cannot find anything related. I have found in the examples (FLEXMEM_Configurations) that the HardFault shall happen when accesing beyond the configured TCM size, but I'm getting the crash at the base addresses.

 

uint16_t* _tcmData = (uint16_t*)0x30000000;

int main()
{
    ... //system init etc..
    _tcmData[0] = 0x1234; //Hard_Fault crash here
}

 

4 REPLIES 4
tjaekel
Lead

VERY INTERESTING (and confusing)!

I play right now also with the STM32N6 - I tried your issue on on my project... and YES: it can crash in HardFault_Handler (but see below: it depends just on how you compile with debug options!)

First, I thought:
A non-secure vs. secure issue (DTCM 0x30000000 is Secure, 0x20000000 is Non-Secure). So, accessing DTCM as secure when main() is launched as non-secure (potentially) could cause such an issue. But it does NOT!

It just depends on:
How you set Optimization level! VERY STRANGE:

  • if I set Optimization level to "none (-O0)" - it crashes in HardFault_Handler!
  • if I set "Optimize for debug (-Og)" - it WORKS!

I use an STM32N6 project with FSBL build. It really just depends on how I set the debug level!
Secure and non-secure address location does not have an effect! (it crashes with both address locations if not -Og!)

What is this?
(I have realized already: the STM32N6 is very "delicate": sometimes it works, sometimes not - it seems to depend meanwhile on "how" I generate the code (with vs. without debug optimization, FSBL vs. Appli, ...).

Here the details:
I do also in main():

int main(void)
{
  int no = 6;
  /* USER CODE BEGIN 1 */
  XSPI_RegularCmdTypeDef sCommand = {0};
  XSPI_MemoryMappedTypeDef sMemMappedCfg = {0};

  uint16_t index = 0;
  uint16_t res = 0;
  uint32_t address = 0;
  __IO uint8_t step = 0;
  __IO uint8_t *mem_addr;

#if 1
  {
	  uint16_t* _tcmData = (uint16_t*)0x20000000;	//0x30000000 is secure memory, 0x20000000 is non-secure
	  _tcmData[0] = 0x1234;
	  if (_tcmData[0] == 0x1234)
		  testVar = 1;
  }
#endif

Just toggle debug level for code generation!

This is a debug session with debug level -Og:

tjaekel_0-1735968239969.png

This works fine!: I can write and read DTCM as secure and non-secure (0x30000000 vs. 0x20000000).

This is a debug session with none, as -O0:

tjaekel_1-1735968389144.png

This CRASHES: both addresses accessed result in a HardFault_Handler.

What is this?

I assume: the debugger has an effect on secure vs. non-secure access permission or system configuration done (by debugger instead of code).
(the system behavior should not not have any effect if generated for debugger and/or using debugger to let execute my code)

I am pretty "shocked" being able to replicate this issue (and I am very confused, losing my confidence in this N6 MCU...)

 

 

 

filipxsikora
Associate II

Very interesting findings @tjaekel .

I can confirm, if I switch to -O2, then it does not crash into the HardFault when accessing the memory. However, this is far from over.

To address your points:

(I have realized already: the STM32N6 is very "delicate": sometimes it works, sometimes not - it seems to depend meanwhile on "how" I generate the code (with vs. without debug optimization, FSBL vs. Appli, ...).

Same here. The N6 goes wild on me like 50 times a day, when I have to physically reconnect the USB to reset the ST-Link and Power. Reset button does not "fix" things.

(I'm using the N6-Nucleo board)

 

A non-secure vs. secure issue (DTCM 0x30000000 is Secure, 0x20000000 is Non-Secure). So, accessing DTCM as secure when main() is launched as non-secure (potentially) could cause such an issue. But it does NOT!

I'm no expert in this secure/non-secure thing. Actually, it just bothers me, I don't want it, but it is what it is. But I was thinking, my code and data runs from secure (using the Appli LRUN.ld, which places the code and data into the 0x34000400 AXI SRAM, which is secure. When I was checking addresses of peripherals, they were all in the 0x50000000 range, again, secure. So my thinking was - I'm in secure, I shall use secure.

 

I hope these are mostly ST-link issue, fixable by FW update of ST-link. It is a new product, it is very complex, so yeah, I'm expecting some newborn pains.

 

Because - when I move my stack into the DTCM, it works.

What does not work for me is ITCM. I just cannot make it run no matter what. I have my code and approach from STM32H7:

  • Create section in linker for ITCM funcs
  • Create symbols at the section boundary
  • Load the ITCM mem from ROM (right now in N6_LRUN.ld loading from RAM) at startup.
  • Done

This has always worked for me. But not in N6 case, I just always get a HardFault when calling any func placed at ITCM.

filipxsikora
Associate II

Also tried accessing the memory through STM32CubeProgrammer. I can access basically any address:

  • 0x24000000/0x34000000 - AXI RAM NSEC/SEC
  • 0x40000000/0x50000000 - Peripherals NSEC/SEC
  • 0x70000000 - XSPI Flash
  • 0x08000000/0x18000000 - BootROM NSEC/SEC

But, when I try to access 0x00000000 or 0x10000000 or 0x20000000 or 0x30000000 it gives me an error.

So I can't check or confirm, what is in the ITCM (if anything).

 

Please ST, have a look at this.

filipxsikora
Associate II

Update: I have also tried to load the ITCM mem "directly", without the intermediate step of loading from ROM/RAM and this works, surprisingly. When debugging, I can see the SP switch to 0x10000000 and executes the code in ITCM normally. Really, really weird and unpredictable behaviour. Also it is useless.

 

Edit: Even better, when I load the ITCM directly, it looks like the "connection" to the ITCM gets somehow "enabled" and as long as I don't disconnect the power, I can then do the normal approach with loading the contents of the ITCM from RAM/ROM. And it works. But, when I disconnect the power, reconnect and upload exactly the same code again -> HardFault.