Skip to main content
Visitor II
May 8, 2024
Solved

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

  • May 8, 2024
  • 3 replies
  • 3441 views

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?

    This topic has been closed for replies.
    Best answer by mƎALLEm

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

    3 replies

    ST Employee
    May 8, 2024

    Hello @eds,

    Are you enabling the data cache? 

    check this article: DMA is not working on STM32H7 devices

    edsAuthor
    Visitor II
    May 8, 2024

    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.

    Graduate II
    May 8, 2024

    Show ld and code. How is working optimization level ?

    edsAuthor
    Visitor II
    May 8, 2024

    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))}
    }

     

     

    Graduate II
    May 8, 2024

    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.

    mƎALLEmAnswer
    Technical Moderator
    May 8, 2024

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

    edsAuthor
    Visitor II
    May 8, 2024

    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.