cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet not working on STM32H7 when GCC compiler is in O0 (None) optimization

Marina Brener
Associate III
Posted on April 04, 2018 at 15:04

Hello,

I am working on Eth + RTos on Atollic TrueStudio environment.

I changed the Linker file so that the DMA will use section

0x24000000 

and placed my buffers in this section.

Also, I put this buffer from arch.h into this section as well:

#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]  __attribute__((section('.sram1')));

If I work in debug (Og) optimization mode, everything works smoothly. 

If I remove the optimization and make it OO, the Ethernet stops working. 

Did someone encountered this issue? 

Any assistance will be great. 

attached my linker file:

/* Entry Point */

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */

_estack = 0x20020000; /* 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 */

/* Specify the memory areas */

MEMORY

{

DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K

RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K

RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K

ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K

FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K

DMARxDscr_Memory (xrw) : ORIGIN = 0x30040000, LENGTH = 0x60

DMATxDscr_Memory (xrw) : ORIGIN = 0x30040060, LENGTH = 0x19F

Rx_Buff_Memory (xrw) : ORIGIN = 0x30040200, LENGTH = 0x2000

}

/* Define output sections */

SECTIONS

{

/* The startup code goes first into FLASH */

.isr_vector :

{

. = ALIGN(4);

KEEP(*(.isr_vector)) /* Startup code */

. = ALIGN(4);

} >FLASH

/* The program code and other data goes into FLASH */

.text :

{

. = ALIGN(4);

*(.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))

. = ALIGN(4);

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

} >FLASH

/* Constant data goes into FLASH */

.rodata :

{

. = ALIGN(4);

*(.rodata) /* .rodata sections (constants, strings, etc.) */

*(.rodata*) /* .rodata* sections (constants, strings, etc.) */

. = ALIGN(4);

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

/* 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);

} >DTCMRAM

.sram4 :

{

. = ALIGN(4);

*(.sram4); /* .data sections */

*(.sram4*); /* .data* sections */

} >RAM_D3

.RxDecripSection :

{

. = ALIGN(4);

*(.RxDecripSection); /* .data sections */

*(.RxDecripSection*); /* .data* sections */

} >DMARxDscr_Memory

.TxDecripSection :

{

. = ALIGN(4);

*(.TxDecripSection); /* .data sections */

*(.TxDecripSection*); /* .data* sections */

} >DMATxDscr_Memory

.RxArraySection :

{

. = ALIGN(4);

*(.RxArraySection); /* .data sections */

*(.RxArraySection*); /* .data* sections */

} >Rx_Buff_Memory

.sram1 :

{

. = ALIGN(4);

*(.sram1); /* .data sections */

*(.sram1*); /* .data* sections */

} >RAM_D1

/* Remove information from the standard libraries */

/DISCARD/ :

{

libc.a ( * )

libm.a ( * )

libgcc.a ( * )

}

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

}

Thanks,

Marina

4 REPLIES 4
Posted on April 04, 2018 at 19:48

If I remove the optimization and make it OO, the Ethernet stops working. 

Try to elaborate.

JW

Marina Brener
Associate III
Posted on May 08, 2018 at 16:53

I was missing MPU configuration! 

If anybody will have a problem with lwip not working when compiler optimization is None (O0) but working otherwise, try configuring a Memory protection Unit.

This post helped me:

 
Posted on May 08, 2018 at 17:11

Yes, I couldn't put my finger on it.. 

I was compiling my Atollic project with optimization Og (debug level), I had a working lwip with DMA regions set up correctly via the linker. Ethernet was working great even though I did not configure an MPU. When I changed the optimization to O0 and it broke lwip communication. 

I added an MPU based on the demo project and MAGIC!!

I guess, with optimizations, the compiler was smart enough to realize it needs to allocate the regions and make it

Strongly-orde

red ty

pe 

for the DMA descriptors. Any thoughts or corrections? 
GreenGuy
Lead
Posted on May 21, 2018 at 23:31

First thing I see right off the bat is the estack callout as '_estack = 0x20020000; /* end of RAM */'

If any buffers are being allocated there that transfer using DMA, the program will end up in the hardware fault interrupt as the stack and heap are in the DTCM and DMA cannot reach that area.  Of course this not the case for your ethernet buffers but doing similar development with the H7 I have had only trouble trying to put the heap and stack in the DTCM.