Search code examples
cstm32

Ethernet is stopped after using global variables in STM32


I am using STM32H735ZGTx_ LQFP144. I have done Ethernet configuration according to this link https://controllerstech.com/stm32-ethernet-1-connection/

If I am not using any global in any of the source file, I am not facing any issue, Ethernet is working fine.

Whenever I declare and use global variables or static variables, I am facing some issue and the Ethernet is stopped.

I am getting different errors based on the global variables size, as follows

char buff[5] = "123"; //initialized
Error : Hard Fault error 

char buff[100]; // uninitialized 
Error: ssertion "pc>custom_free_function != NULL" failed at line 767 in../Middlewares/Third_Party/LwIP/sr/core/pbuf.c

char buff[200]: //uninitialized
Error:
Assertion "pbuf_free: p->ref > 0" failed at line 753 in../Middlewares/Third_Party/LwIP/src/core/pbuf.c
Error: Assertion "mem_trim: legal memory" failed at line 721 in ../Middlewares/Third_Party/LwIP/src/core/mem.c

Changing the variable size is changing the errors. I'm new to STM, please help me with this issue.

I have checked the address of global variables, all are stored in RAM_D1.

In the hard fault, I noticed that, it's causing error when it is in pbuf_free() function.


Solution

  • I have found that some of the STM32H7x series have Ethernet issues. Although we configured the address in CubeMX in ethernetif.c but we need to place RX_POOL buffer at specific RAM.

    /* USER CODE BEGIN 2 */
    #if defined ( __GNUC__ ) /* GNU Compiler */
    __attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
    #endif
    /* USER CODE END 2 */
    

    Modify the linkerscript (*.ld) that the ETH descriptors and buffers are located in D2 SRAM. Also it is recommended to place all RAM to RAM_D1. In STM32CubeMX generated project, the "_FLASH" suffix linkerscript should be modified, which is used by default

    (e.g.: STM32H750XBHx_FLASH.ld). The "_RAM" suffix linkerscript is template for executing code from internal RAM memory.

    
    } >RAM_D1
    
      /* Modification start */
      .lwip_sec (NOLOAD) :
      {
        . = ABSOLUTE(0x30040000);
        *(.RxDecripSection) 
        
        . = ABSOLUTE(0x30040060);
        *(.TxDecripSection)
         /* Rx_Pool section must be added in linker */
        . = ABSOLUTE(0x30040200);
        *(.Rx_PoolSection)  
      } >RAM_D2
    

    After these modifications, my issue was resolved.
    Rx_Pool stores the pbufs, but due to improper alignment it was overwriting some of the pbuf pointers.

    Note: If you are storing Rx_Pool in some other RAM or address, the alignment must be proper, or else it will overwrite again.