cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 Hardfault when DMA is used with Optimization to speed is open

eds
Associate III

I'm working on a project using an STM32H7 series MCU with FreeRTOS. I've customized the .ld file to configure the stack and have set up the internal ADC and DMA to continuously read and store ADC values. I've statically assigned the DMA data registers starting at 0x24000000. Initially, my project worked fine, but I needed to increase the execution speed, so I enabled compiler optimizations for speed.

However, after enabling optimizations, I started experiencing a HardFault error which I've been unable to resolve. The error occurs only after the optimizations are turned on. Here are the settings and configuration details:

  • MCU: STM32H7 series
  • RTOS: FreeRTOS
  • Memory Configuration: Customized .ld file, DMA data registers at 0x24000000
  • Compiler Settings: Optimization for speed enabled

I suspect the issue might be related to memory access or alignment due to the optimizations altering how quickly certain operations are executed. Has anyone faced a similar issue, or can anyone suggest potential fixes or debugging strategies to resolve this HardFault error?

1 ACCEPTED SOLUTION

Accepted Solutions
SofLit
ST Employee

I suspect the issue might be related to memory access or alignment due to the optimizations altering how quickly certain operations are executed. Has anyone faced a similar issue, or can anyone suggest potential fixes or debugging strategies to resolve this HardFault error?

Hello,

I'm not sure it's an issue of timing issue or a race condition. It could be that the stack is overwritten by the DMA. Where are you locating your stack? in AXI SRAM?

If you change the data to be stored by DMA in another memory like SRAM1 or SRAM2 in D2 domain, what is the result?

PS: please provide the exact H7 part number as the architecture may differ from H7 device to another ..

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.

View solution in original post

10 REPLIES 10
Sarra.S
ST Employee

Hello @eds,

Are you enabling the data cache? 

check this article: DMA is not working on STM32H7 devices

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.

eds
Associate III

Hi @Sarra.S 

No, I am not enabling the data cache. I specifically disabled all cache because of this problem and I changed the DMA data register to the address I mentioned because of that post. It was working okay up until I opened optimization in the compiler.

MM..1
Chief II

Show ld and code. How is working optimization level ?

SofLit
ST Employee

I suspect the issue might be related to memory access or alignment due to the optimizations altering how quickly certain operations are executed. Has anyone faced a similar issue, or can anyone suggest potential fixes or debugging strategies to resolve this HardFault error?

Hello,

I'm not sure it's an issue of timing issue or a race condition. It could be that the stack is overwritten by the DMA. Where are you locating your stack? in AXI SRAM?

If you change the data to be stored by DMA in another memory like SRAM1 or SRAM2 in D2 domain, what is the result?

PS: please provide the exact H7 part number as the architecture may differ from H7 device to another ..

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.
eds
Associate III

The full code of the MCU is STM32H735RGV6, and I tried using SRAM1 as per your suggestion but I again came face to face with the same problem. 

eds
Associate III

I don't understand what you mean by optimization level. My .ld file is this:

 

 

 
   .image_hdr : 
  {
    KEEP (*(.image_hdr))
  } >FIRMWARE
 */


INCLUDE memorymap.ld

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */


/* Define output sections */
SECTIONS
{


  /* The startup code goes first into FIRMWARE */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FIRMWARE
  
  .section_table : 
  {
    . = ALIGN(4);
    __section_table_start = .;
    __text_section_table = .;
    LONG(LOADADDR(.text));
    LONG(    ADDR(.text));
    LONG(  SIZEOF(.text));
    __text_section_table_end = .;
    __rodata_section_table = .;
    LONG(LOADADDR(.rodata));
    LONG(    ADDR(.rodata));
    LONG(  SIZEOF(.rodata));
    __rodata_section_table_end = .;
    __data_section_table = .;
    LONG(LOADADDR(.data));
    LONG(    ADDR(.data));
    LONG(  SIZEOF(.data));
    __data_section_table_end = .;
    __bss_section_table = .;
    LONG(    ADDR(.bss));
    LONG(  SIZEOF(.bss));
    __bss_section_table_end = .;
    __section_table_end = . ;
    
    *(.after_vectors*)
    . = ALIGN(4);
  } >FIRMWARE
  
  .main_text : 
  {
    . = ALIGN(4);
    *startup_*.o (.text .text*)
    *system_*.o (.text .text*)
    *startup_*.o(.rodata .rodata.* .constdata .constdata.*)
    *system_*.o(.rodata .rodata.* .constdata .constdata.*)
    *(.text.main*)
    *libc_nano.a:*(.text .text*)
    *libc_nano.a:*(.rodata .rodata.* .constdata .constdata.*)
    
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } >FIRMWARE

  /* The program code and other data goes into  */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */
    . = ALIGN(4);
  } >RAM_D1 AT> FIRMWARE

  .rodata :
  {
    . = ALIGN(4);   
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >DTCMRAM AT> FIRMWARE
  
  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FIRMWARE
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FIRMWARE
  
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FIRMWARE

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

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FIRMWARE
  
   /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);
  
    /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >DTCMRAM AT> FIRMWARE

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >DTCMRAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM_D1
  
      
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
  
  .mySegment 0x30000000 : {KEEP(*(.mySection))}
}

 

 

From your showed info nobody see how you reserve in ld file space for DMA, and why you dont alocate it in code.

Optimization levels is basic for C compilers. I mean your first working is -O0 , that equal to no optimize. Result is any bad syntaxed code fail after change to higher opt levels.

eds
Associate III

It is at the bottom of the file that is specified as .mySegment

Hello @eds ,

I've noticed that you accepted my solution, are you sure since your reply was: "The full code of the MCU is STM32H735RGV6, and I tried using SRAM1 as per your suggestion but I again came face to face with the same problem. "

Please confirm it was the solution or I need to unmark it.

Thank you.

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.