cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 U5 Hard Fault when using SRAM

PMera.1
Associate II

Hello.

I'm trying to use STM32 U5A5' SRAM (SRAM1,2,3,5) and I'm encountering some very weird behavior.

When I use the entire aforementioned sram blocks, my mcu hard faults.

uint8_t __attribute__((section(".TEST_Section"))) data[1024*1024*2];
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure The Vector Table address */
SCB->VTOR = 0x08000000;

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* Configure the System Power */
SystemPower_Config();
/* GTZC initialisation */
MX_GTZC_Init();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_DCACHE1_Init();
MX_ICACHE_Init();
MX_RAMCFG_Init();
MX_FLASH_Init();
/* USER CODE BEGIN 2 */
printf("ENTRY POINT");
memset(data, 0xAF, sizeof(data)); // WITHOUT THIS LINE, EVERYTHING WORKS OK. This causes a hard fault.
printf("DONE\n");
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

1. This configuration fails. 

PMera1_0-1702386684458.png
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32U5A5xJ Device from STM32U5 series
** 4096Kbytes FLASH
** 2512Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
*****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Memories definition */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K
TEST (xrw) : ORIGIN = 0x20040000, LENGTH = 2240K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
}

/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
KEEP(*(.isr_vector)) /* Startup code */
} >FLASH

/* The program code and other data into "FLASH" Rom type memory */
.text :
{
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)

KEEP (*(.init))
KEEP (*(.fini))

_etext = .; /* define a global symbols at end of code */
} >FLASH

/* Constant data into "FLASH" Rom type memory */
.rodata :
{
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
} >FLASH

.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH

.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH

.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH

.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH

/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections into "RAM" Ram type memory */
.data :
{
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */

_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH

/* Uninitialized data section into "RAM" Ram type memory */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)

_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM

/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM

/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }

/* Unitialized TEST section into "TEST" TEST type memory */
.TEST_Section(NOLOAD) :
{
. = ALIGN(4);
KEEP (*(.TEST_Section))
. = ALIGN(4);
} >TEST

}
 
 
2. This configuration works.
PMera1_1-1702386785300.png
/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Memories definition */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K
TEST (xrw) : ORIGIN = 0x20040000, LENGTH = 1344K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
TEST2 (xrw) : ORIGIN = 0x201a0000, LENGTH = 832K
}

/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
KEEP(*(.isr_vector)) /* Startup code */
} >FLASH

/* The program code and other data into "FLASH" Rom type memory */
.text :
{
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)

KEEP (*(.init))
KEEP (*(.fini))

_etext = .; /* define a global symbols at end of code */
} >FLASH

/* Constant data into "FLASH" Rom type memory */
.rodata :
{
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
} >FLASH

.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH

.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH

.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH

.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH

.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH

/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections into "RAM" Ram type memory */
.data :
{
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */

_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH

/* Uninitialized data section into "RAM" Ram type memory */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)

_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM

/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM

/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

.ARM.attributes 0 : { *(.ARM.attributes) }

/* Unitialized TEST section into "TEST" TEST type memory */
.TEST_Section(NOLOAD) :
{
. = ALIGN(4);
KEEP (*(.TEST_Section))
. = ALIGN(4);
} >TEST

/* Unitialized TEST2 section into "TEST2" TEST2 type memory */
.TEST2_Section(NOLOAD) :
{
. = ALIGN(4);
KEEP (*(.TEST2_Section))
. = ALIGN(4);
} >TEST2

}

 

Im at my wits end. I'm not trying to execute code from ram. Im not using the MPU. I'm simply trying to use those memory blocks in the following config:

1. Main partition, for stack, heap, variables etc.

2. Secondary partition, for data acquisition (used almost exclusively by DMA).

I tried replacing the memset with a simple loop. Interestingly enough, there's a NULL pointer exception there, once i hit the ~1600000th byte. I sincerely have no clue how to debug this.

I'm running the code on a nucleo U5A5, by the way. I'm attaching the project here, in case anyone wants to take a look. The binaries are in cmake-build-debug.

1 REPLY 1
SMill.8
Associate II

Hello,

did you find any solution? I´m experimenting similar issue when using SRAM2 in my U5756CI microcontroller. In my case, exiting from STOP3 mode and accessing a variable located at SRMA2 provokes a Hard Fault. However, exiting from STOP2 works correctly.