on
2020-03-11
07:50 AM
- edited on
2024-06-17
06:55 AM
by
Laurids_PETERSE
This readme is intended for STM32CubeIDE version 1.9.0 and STM32CubeH7 version 1.10.0. For older tool versions please see older version of this readme in the repository.
If you have any questions regarding Ethernet topics in general, please visit our MCU forum and create a thread. Doing so will provide you with a shorter response time.
Example project code and older version of this article is provided on Github: https://github.com/stm32-hotspot/STM32H7-LwIP-Examples. Detailed how to step-by-step is provided below.
ETH_CODE
keywordVersion | STM32CubeIDE version | STM32CubeH7 version | Description / Update | Date |
---|---|---|---|---|
1.2 | 1.9.0 | 1.10.0 | Ported to new IDE/library version. Ethernet driver reworked in new library release. Added iperf measurement and TCP/IP settings tuned. Published on Github | August 9th 2022 |
1.1 | 1.6.1 | 1.9.0 | Added Cortex-M4 base examples | July 19th 2021 |
1.0 | 1.6.1 | 1.9.0 | Initial release on ST community (with minor changes on Github) | June 21st 2021 |
Using GIT tags it should be easy to find examples for particular version of STM32CubeIDE and HAL library
Below configuration is necessary to achieve good TCP/IP performance
Parameter | Value | Formula | Needs to be changed in MX |
---|---|---|---|
TCP_MSS | 1460 |
|
yes |
TCP_SND_BUF | 5840 |
|
yes |
TCP_WND | 5840 |
|
no |
TCP_SND_QUEUELEN | 16 |
|
yes |
On STM32H74x/H75x devices, all data related to Ethernet and LwIP are placed in D2 SRAM memory (288kB). First 128kB of this memory are reserved for Cortex-M4 on dual-core devices. On single core devices this part can be used for other purposes.
Variable | STM32H74x/H75x address | Cortex-M4 alias | Size | Source file |
---|---|---|---|---|
DMARxDscrTab | 0x30040000 | 0x10040000 | 96 (256 max.) | ethernetif.c |
DMATxDscrTab | 0x30040100 | 0x10040100 | 96 (256 max.) | ethernetif.c |
memp_memory_RX_POOL_base | 0x30040200 | 0x10040200 | 12*(1536 + 24) | ethernetif.c |
LwIP heap | 0x30020000 | 0x10020000 | 131048 (128kB - 24) | lwipopts.h |
For STM32H72x/H73x devices, the D2 SRAM is more limited (only 32kB). The RX buffers need to be placed in AXI SRAM, since they won't fit to D2 RAM, together with LwIP heap. The LwIP heap is reduced to fit the rest of D2 RAM together with DMA descriptors.
Variable | STM32H72x/H73x address | Size | Source file |
---|---|---|---|
DMARxDscrTab | 0x30000000 | 96 (256 max.) | ethernetif.c |
DMATxDscrTab | 0x30000100 | 96 (256 max.) | ethernetif.c |
memp_memory_RX_POOL_base | AXI SRAM (32-byte aligned) | 12*(1536 + 24) | ethernetif.c |
LwIP heap | 0x30000200 | 32232 (32kB - 512 - 24) | lwipopts.h |
Value provided here are an example implementation, other configurations are also possible in order to optimize memory usage. When changing memory layout, the MPU configuration needs to be updated accordingly.
Libraries and middleware is taken from STM32CubeH7 package. So the same licenses apply to the these examples. There is minimum code added on top of STM32CubeMX and HAL libraries, this code is provided AS-IS.
Goal of this example is to:
Although the example is using STM32H750-Discovery, it might be easy to use the same steps for other STM32H7 based boards. The main differences are usually pinout and clock configuration. You might also need to check board solder bridges to make sure the Ethernet is connected to MCU.
Configure clock tree:
The ETH_MDC speed couldn't be changed for some reason, but it doesn't affect the application and it was already fixed in new versions.
This step can be skipped when using Cortex-M4 core.
Above example is for STM32H743 device. For other devices or Cortex-M4 core on dual-core device, different addresses and size might be necessary. Please refer to section Memory layout
When using dual-core device and running Ethernet on Cortex-M7 core, it must be ensured that memory used by Ethernet is not used by Cortex-M4. Also note the Cortex-M4 can use different address alias for D2 RAM
In "Key options" tab:
Save project to some folder of your selection. Now you can generate the project for IDE. We will use STM32CubeIDE in this example, but it should work with other IDEs.
There are several places where some additional code should be placed, also depending on selected device. In the examples all these places are marked with comment containing
ETH_CODE
and some basic explanation. Searching for
ETH_CODE
can show all these places.
Only main interesting points are mentioned below:
/* USER CODE BEGIN 2 */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ #pragma location = 0x30040200 extern u8_t memp_memory_RX_POOL_base[]; #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ __attribute__((at(0x30040200)) extern u8_t memp_memory_RX_POOL_base[]; #elif defined ( __GNUC__ ) /* GNU Compiler */ __attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[]; #endif /* USER CODE END 2 */
/* USER CODE BEGIN 1 / #undef LWIP_PROVIDE_ERRNO #define LWIP_ERRNO_STDINCLUDE / USER CODE END 1 */
This step should be skipped for Keil and IAR, since they support placing variables at specific address in C code. 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) . = ABSOLUTE(0x30040200); *(.Rx_PoolSection) } >RAM_D2 /* Modification end */ /* Remove information from the compiler libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) }
The memory definitions at the beginning of the linkerscript should look like:
MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K 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 }
For dual core devices it is better to restrict RAM_D2 section to avoid collision with Cortex-M4. Please see the linkerscripts in examples.
#include “lwip/udp.h” #include <string.h>
/* USER CODE BEGIN 5 */ const char* message = "Hello UDP message!\n\r"; osDelay(1000); ip_addr_t PC_IPADDR; IP_ADDR4(&PC_IPADDR, 192, 168, 1, 1); struct udp_pcb* my_udp = udp_new(); udp_connect(my_udp, &PC_IPADDR, 55151); struct pbuf* udp_buffer = NULL; /* Infinite loop */ for (;;) { osDelay(1000); /* !! PBUF_RAM is critical for correct operation !! */ udp_buffer = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM); if (udp_buffer != NULL) { memcpy(udp_buffer->payload, message, strlen(message)); udp_send(my_udp, udp_buffer); pbuf_free(udp_buffer); } } /* USER CODE END 5 */
Now you should be able to ping the device and receive UDP messages, assuming that you configure IP address 192.168.1.1 for the receiving device (the 192.168.1.0/24 network is used by attached examples). On Linux machine you can observe the messages with the following command:
netcat –ul 55151
When facing issues with your own project:
If you see any issue with these examples please fill an issue inside this repository. If you face some difficulties, but not sure if this is an issue you can start discussion inside this repository, or you can start thread on ST community
Exact size required for different stacks might depend on used compiler and optimization flags. Same goes for FreeRTOS heap size, since thread stacks are allocated from this heap.↩
Some addresses and sizes depend on the device or core used. Please refer to section Memory layout.↩↩↩↩
If you have any questions regarding Ethernet topics in general, please visit our MCU forum and create a thread. Doing so will provide you with a shorter response time.
It is nice to have the description, thanks. But normally I would expect CubeMX generate everything as needed - up to ping working, especially for distributed boards - currently talking about Nucleo H743ZI2. So embedded developers can concentrate on application development and not fight with any standard peripherals. I already spent many days in past years fighting with Eth on F7 and H7 boards - one problem being that mentioned LwIP_HTTP_Server_Netconn_RTOS have very different structure from code generated by CubeMX so it is almost impossible to merge these two (when LwIP_HTTP_Server_Netconn_RTOS works with some limitations, while default code from CubeMX does not).
I hope ST will move in that direction in next years, so CubeMX will generate everything as needed for Nucleo/Eval boards regarding Ethernet.
I followed the instructions and got the demo working on a Nucleo-H723ZG eval board. My setup was based on CubeMX V6.4.0 and STM32Cube FW_H7 V1.9.1.
Now, I updated to CubeMX V6.5.0 and it offered an update to STM32Cube FW_H7 V1.10.0. I migrated my project to the new firmware lib and now the demo does not work anymore, i.e. I had DHCP client and ping working before, but now I'm not getting an IP address via DHCP anymore.
There seem to be a lot of changes to the ethernet driver, e.g. the memory ranges for the RX / TX buffers, .RxArraySection is now complete gone. I guess that the MPU settings and the linker script need to be adjusted accordingly.
Can you please update the step-by-step guide and provide an updated example set?
At least for now, I'm going to stick with the old version and will not migrate my project.
Hi @bernd Bartmann, I had also this problem, it seems there are not any working instructions for the new HAL version. What helped me was the example in \STM32Cube\Repository\STM32Cube_FW_H7_V1.10.0\Projects\NUCLEO-H723ZG\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS, there you can see how to set the addresses so that it is working. Apart from moving the addresses, one of the sections was also renamed (RxArraySection -> Rx_PoolSection).
In the linker file:
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000200);
*(.TxDecripSection)
. = ABSOLUTE(0x30000400);
*(.Rx_PoolSection)
} >RAM_D2 AT> ROM
In the MPU settings:
And finally in ethernetif.c, there is missing setting the rx pool base to the correct address:
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30000400
extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif
I have taken those things directly from the example.
Hope that this helps
Karel
Thanks a lot Karel! This made it working again for me as well.
The only thing I need to figure out is an assert that I'm getting during startup:
Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
I'll debug this further.
Best regards,
Bernd
Starting with the STM32 Cube FW_H7 1.10.0 version, it becomes impossible to specify the correct location of the ethernet descriptors and buffers officially recommended here in paragraph 10.2 for CortexM4.
Migrating example (p.11. Attached examples) STM32H745_Nucleo_M4_ETH.ioc from 1.9 to 1.10 gives the result shown in the picture.
If you are trying to run Ethernet on Cortex M4 while having all it in the M7 region (0x3000000), it still works. But it works very bad and unstable, even a regular ping test gives from 3 to 20% of failed packets, and if you increase the size of the ping packet, it falls immediately.
So... can you please you please update your examples to current STM32 Cube FW_H7 version ?
Hello @IOvch ,
thank you for your feedback.
I have in plan to update this material to be compatible with new release of STM32Cube_FW_H7. The Ethernet driver in v1.10.0 was reworked, so there could be some other catches in the configuration.
However the issue you describe is quite strange. Are you sure that the memory used for Ethernet (0x30000000) is not used by the program for other purposes through the alias (0x10000000)?
There could be some slow down, but I would expect it to fail completely.
Best regards,
Adam Berlinger
Hello @Adam BERLINGER !
Thank you for your reply!
I didn't implement anything else - only ethernet on M4 core. You can try to create a new empty project to run ethernet on M4 with STM32 Cube FW_H7 1.10.0. And this does not work at all when used in RTOS mode.
@Adam BERLINGER It seems to be a more serious problem than just a descriptors location:
Hello @IOvch ,
the community thread you linked is regarding STM32F4 devices, which use different Ethernet driver, so I don't this is relevant for STM32H7. I also roughly checked in H7 driver code and I don't see the same issue(s).
I added new section "10. STM32Cube_FW_H7_V1.10.0 (and newer) specific issues" maybe it will help with your issue.
Best regards,
Adam Berlinger
Hi Laura, I have really appreciated the work you've done here! I am wondering if you could shed some light on the "32KB" region size for the MPU region? I would have expected that it would be a 288KB region size, to encapsulate the entire D2 SRAM. I am working to develop a better understanding of this as I am trying to blend this knowledge with the article for getting DMA to work with the Data Cache Enabled: Knowledge Article "DMA is not working on STM32H7 devices" -- and so I am adding a ".dma_buffer" region to the modifications described here with the ".lwip_sec" region. Thanks!
Hi @Scott F,
@Adam BERLINGER is the author of the article, he will be able to help you!
Exactly the same problem :(
Please, check default value for:
#define ETH_RX_BUFFER_SIZE 1000
looks like it should be 1536 (please, see comment from Alexander Kvashin at https://community.st.com/s/question/0D73W000001OsEOSA0/detail?s1oid=00Db0000000YtG6&s1nid=0DB0X000000DYbd&emkind=chatterCommentNotification&s1uid=0050X000007vlPS&emtm=1656688370859&fromEmail=1&s1ext=0) as well as all discussion regarding DMA errors
Hello @Adam BERLINGER ,
thanks for your reply and updating the article!
But I'm talking about ethernet running on the M4 CORE as part of STM32H7 with new version of FW_H7_V1.10 in RTOS mode. On the M7 core it works as is... and on the M4 its not working even with your last reccomendations.
Your attached examples are perfect, but can you please update just one of them? Just a simple ping test on M4 CORE of STM32H7, please! It would remove SO MUCH questions at once! Such as:
In the link I sent, in comments, It talks exactly about the poor transfer of the Ethernet driver of the M7 core to the M4 as part of the STM32H7 in FW_H7_V1.10. There is even an internal ticket number 126954. But if this has nothing to do with this - Ok.
I just want to make ethernet work on M4 of STM32H7 with FW_H7_V1.10 and FreeRTOS.
Best regards!
IOvch
Very nice article. It has helped me a lot in order to be able to build a working Ethernet project.
However, I'd like to point a possible bug I've found just in case it avoids some headache to anyone else. If you run the app and unplug and plug the Ethernet cable back, it stops working. Modifying a line towards the end of ethernet_link_thread() function (in ethernetif.c) makes it work correctly:
if(linkchanged)
{
/* Get MAC Config MAC */
HAL_ETH_GetMACConfig(&heth, &MACConf);
MACConf.DuplexMode = duplex;
MACConf.Speed = speed;
HAL_ETH_SetMACConfig(&heth, &MACConf);
HAL_ETH_Start(&heth); // <------------------- This should be HAL_ETH_Start_IT(&heth);
netif_set_up(netif);
netif_set_link_up(netif);
}
I'm using STM32CubeIDE 1.10.0 and STM32CubeMX 6.6.0 with STM32H745 MCU.
Hi, @Adam BERLINGER, I second the request for comment about points 2, 3 and 4. As @IOvch mentions, in the text you first want us to set LWIP_RAM_HEAP_POINTER to 0x30044000 and MEM_SIZE to 16360, then in the last generic section you say
And LWIP_RAM_HEAP_POINTER set to 0x30044B00, with MEM_SIZE12000
So, which one is correct? For me the first set of values worked.
Regards,
Karel
Hi all,
You have write "LWIP_RAM_HEAP_POINTER set to 0x30044B00" not shure, but maybe you mean 0x30044800 instead? Cause its equals to 18kb.
In the new section 10, Adam explains it. The size of the memory pool is 1536 bytes x 12 = 18432 bytes = 18 KB = 0x4800. Because the Rx_PoolSection section (memory pool) is located at 0x30040200:
.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30040000);
*(.RxDecripSection)
. = ABSOLUTE(0x30040060);
*(.TxDecripSection)
. = ABSOLUTE(0x30040200);
*(.Rx_PoolSection)
} >RAM_D2
if you add 0x4800 (18KB), you get 0x30044A00. This is the position where the memory pool ends. I think Adam has chosen the next "round" value of 0x30044B00, making 0x100 = 256 bytes of gap between this pool memory and the lwIP RAM heap pointer. So this lwIP RAM heap is placed at 0x30044B00.
Then, because SRAM3 ends at 0x30048000, you have a free memory space of 0x30048000 - 0x30044B00 = 0x3500 = 13568 bytes = 13,2KB. I think Adam prefers to be "safe" and use only 12 KB of that memory. That's why he says that you should set a MEM_SIZE of 12000 (Section 7. lwIP configuration, "...in key options tab configure MEM_SIZE to 16360...)
You have write "This should ensure that all Ethernet specific buffers/descriptors are placed in SRAM3". I thought that we use only RAM_D2 for it.
I think you get domains and RAMs mixed up. RAM_D2 (Domain 2) is composed of SRAM1, SRAM2 and SRAM3.
Best regards,
Noti.
It says 192.168.1.10 IP address is used in the LwIP configuration. Is this IP address the IP address it gives to the kit it uses? Or is it the PC!'s IP address? and according to which notation it gives this IP address.
Hello! @Adam BERLINGER @David Notivoli @heveskar
During all this time, I have not been able to run ethernet on the M4 core under FreeRTOS. I'm not doing anything superfluous - just an new empty project with HAL FW_H7 1.10.0. Surprisingly, ethernet works on the M4 CORE out of the box even without any changes (except for increasing the GPIO speed).
But... only without FreeRTOS. If you add it, then none of the manipulations suggested here or in neighboring branches help.
I also noticed that with FreeRTOS for M4, it generates in ethernetif.c file a call to SCB_InvalidateDCache_by_Addr that cannot be executed, so I'm just removing that call...
Maybe in this case it is necessary to configure the MPU on both cores?
I have attached two projects - there is only basic functionality, nothing but ping. They are almost compatible with Nucleo-745 except for a couple of pins. It works without FreeRTOS (M4 core), but if you added it.. nothing helps.
I have lost hope for a working ethernet example on a new version of the libraries. But maybe there will be some ideas?
@IOvch Unfortunately I do not have a board with both cores, but for FreeRTOS, wouldn't help you replacing
#define INTERFACE_THREAD_STACK_SIZE ( 350 )
in ethernetif.c with
#define INTERFACE_THREAD_STACK_SIZE ( 512 )
I do not know if it will help you, but I have discovered that 350 is not enough.
@heveskar Thanks for your advice! It didn't help, but I'll use it by default in the future
I think some deeper MPU setup is needed here. But... it works without RTOS, so it's not a fact that this is the case.
Hi,
if I try to modify ETH_RX_BUFFER_SIZE to 1536 or 1524 project doesn't work, even if the memory is always rigth placed and aligned.
Anyone knows why this value is 1000?
Hi,
Is there a reason to select the clock at 400MHz, instead of the maximum allowed?
I am using H723 and the clock can be 550MHz, do I have to reduce it to 400?
Hello @ktrofimo and @FBelt.1 ,
The ETH_RX_BUFFER_SIZE should be set to 1536. Sometimes (for unknown reason to me) the STM32CubeMX selects 1524. So far I haven't faced 1000 value on STM32H7.
I know there are were some issues on F4 family where this was hardcoded to the driver.
If this issues is not related to CubeMX configuration, could you be please more specific? Maybe I misunderstood.
Adam
Hello @Ec ,
the 192.168.1.10 IP is for the board. I always configure 192.168.1.1 on the PC side, however different IP address from the subnet could be also viable.
Hi,
Newbie here for ETH.
Seems that my Nucleo-H743ZI is not showing in my router.
My setup is Win10 with the ff info:
I have modified the code like so:
in lwipopts.h
/* USER CODE BEGIN 1 /
#undef LWIP_PROVIDE_ERRNO
#define LWIP_ERRNO_STDINCLUDE
#define LWIP_RAM_HEAP_POINTER (0x30044000)
/ USER CODE END 1 */
in ethernetif.c
/* USER CODE BEGIN 2 */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30040200
extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((at(0x30040200)) extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __GNUC__ ) /* GNU Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#endif
/* USER CODE END 2 */
in LWIP.c
IP_ADDRESS[0] = 192;
IP_ADDRESS[1] = 168;
IP_ADDRESS[2] = 50;
IP_ADDRESS[3] = 10;
NETMASK_ADDRESS[0] = 255;
NETMASK_ADDRESS[1] = 255;
NETMASK_ADDRESS[2] = 255;
NETMASK_ADDRESS[3] = 0;
GATEWAY_ADDRESS[0] = 192;
GATEWAY_ADDRESS[1] = 168;
GATEWAY_ADDRESS[2] = 50;
GATEWAY_ADDRESS[3] = 1;
My STM32H743ZITX_FLASH.ld
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x24080000; /* 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
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
RAM (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
}
/* 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 */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 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;
} >RAM_D1
/* 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
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x30040000);
*(.RxDecripSection)
. = ABSOLUTE(0x30040060);
*(.TxDecripSection)
. = ABSOLUTE(0x30040200);
*(.RxArraySection)
} >RAM_D2
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Did I miss something?
Only the orange LED in the LAN port is blinking.
Can you possibly add UART for debug messages and/or the LED for indication?
I also tried to migrate based on the How to here. Project set up with StmCube, then migrated to 1.10.x.
As with you both I also get one or some
Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
at startup on both a
I tried to debugging. No luck for 2, 3 days.
Aside from this (or because of this) the Ethernet communication is very instable.
I made the observation that - also at startup - some allocated RX pBufs in ethernetif.c never will be deallocated and therefore sometimes the buffer pool is full (12, see ETH_RX_BUFFER_CNT) and I get communication issues at startup.
Have you managed the issue for now @Bernd Bartmann , @ktrofimo ?
I believe that there are some issues with the MPU setup and the linker file locations for the TX descriptor section. Perhaps I don't understand some of the details though.
A ETH_DMADescTypeDef is 40 bytes, 10 integers of 4 bytes each, and DMARxDscrTab has 4 of them for 160 bytes or 0xA0. DMATxDscrTab is the same 160 bytes or 0xA0. These are placed via the info in the linker file at specific start locations.
So if DMARxDscrTab is placed by the linker file at 0x3004 0000 it will extend to 0x3004 009F,
DMATxDscrTab is placed at 0x3004 0060 for 0xA0 bytes, which is overlapping with DMARxDscrTab.
Ooops?
The MPU setup declares a 32k region starting t 0x3004 0000, and another with the same start address for 256B to contain the DMA descriptors. This second region would extend to 0x3004 00FF. The transmit and receive descriptors are a total of 160+160 = 320 bytes, so the 256B region won't apply the appropriate shareability or bufferabiltiy to the complete transmit descriptor table. A better length for the second region is 512B.
The receiver pool placement seems to be okay, but I don't understand what the LWIP_RAM_HEAP_POINTER is all about and what protections the RX Pool requires. There is a comment "And LWIP_RAM_HEAP_POINTER set to 0x30044B00, with MEM_SIZE12000. This should ensure that all Ethernet specific buffers/descriptors are placed in SRAM3." But those values would have the heap completely in SRAM2. SRAM3 doesn't begin until 0x3008 0000, far above the 0x3004 79E0 end address of the pool. Can you clarify this?
since "Your administrator has disabled feed post and comment deletions."
please see below ..
Hi there!
I am using the current provided CubeIDE (STM32CubeIDE Version: 1.10.1 Build: 12716_20220707_0928 (UTC)) CubeMX 6.6.1 and H7 Firmware package F1.10.0
I've used the above step by step instruction to get the
running on a STM32H723ZG Nucleo-Board including the described fixes
Flash.ld file was changed to
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
}
and
/* Modification start */
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000060);
*(.TxDecripSection)
. = ABSOLUTE(0x30000200);
*(.Rx_PoolSection)
} >RAM_D2
/* Modification end */
LWIP_RAM_HEAP_POINTER set to 0x30004B00, with MEM_SIZE12000
Testing is done with termial program Hercules with serveral ping and connect/diconnect cycles. Start up and connect diconnect run smooth at first, but after a while (or a unplug/replug of Ethernet cable) the device will still ping but refused connection.
Test:
Sending ICMP ECHO REQUEST to module <- frist ping on start up
Received ICMP ECHO REPLY
Connecting to 172.16.17.100 ...
Connected to 172.16.17.100 <- frist connect OK
Connection closed
[.. will continue to be OK for the next 20+ connections ]
Connecting to 172.16.17.100 ...
Connected to 172.16.17.100
// diconnect cable
Connection refused by remote host <- terminal recognized disconnect OK
Connection closed
// reconnect cable
Sending ICMP ECHO REQUEST to module <- frist ping on reconnect OK
Received ICMP ECHO REPLY
Connecting to 172.16.17.100 ...
Connected to 172.16.17.100 <- frist connect OK
Connection closed
Connecting to 172.16.17.100 ...
Connected to 172.16.17.100 <- second connect OK
Connection closed
Connecting to 172.16.17.100 ...
Connected to 172.16.17.100 <- third connect FAIL
Connection refused by remote host
Connection closed
Sending ICMP ECHO REQUEST to module <- but ping still works
Received ICMP ECHO REPLY
I think it might be some MPU setup or MEMORY assignment issue.
For convienece I'va added a minimal example
address is 172.16.17.100 Port 80
ping, connect and send a string (e.g. ECHO TEST) the server will reply the string and diconnect
Any help would be highly appreciated!
Regards!
Hi,
After migrating my project to 1.10.1, I have made the necessary changes as this article describes.
But here is the picture of the cubemx perspective. I cannot figure out what to do to fix it.
Have a nice day.
This article is very helpful with MPU and _FLASH.LD settings to make project running on
NUCLEO-H723ZG without freeROTS for Ethernet.
The link looks working since plugging and unplugging cable indicating "Link Up" and "Link Down".
However, the Ping is not working.
The setting LWIP_ICMP is 1.
Not sure any functions need to be called after MX_LWIP_Init() to make Ping working?
JYI
I was attempted to apply a similar method to Nucleo-F746ZG without FreeRTOS, just UDP transmission and it did not work. Shall I send the attached project? I'm using Cube 1.10.1, STM32Cube FW_F7 V1.17.0 and most recently CubeMX. I do note, it is a single-core M7 and a single RAM bank. I have placed the RAM within the linker and set 192.168.41.5 as IP address which did not appear on Wireshark. I also have WIndow IPV4 setting to 192.168.41.42 with subnet mask 255.255.255.0. It did not respond to the ping test, and no UDP emitted from 500mSec loop.
In addition: the hardware is working fine via earlier code (System Workspace) which means my setup is working and also tested with ethernet STM demo code.
Hi,
I followed this article to create the test project on my evaluation board, but ping is not working. I did some debug, the ARP message can be received correctly, but looks like the data can't be sent out, even the call HAL_ETH_Transimit() returns OK. Do you have any idea what else should be checked here?
Hello there, I'm a new one at STM32H745-DISCO, I download the ethernet example from this website,
added the DATA_IN_D2_SRAM and Hello UDP message, then Build and Run the code on my board STM32H745XIH6 successfully.
but I can't receive "Hello UDP message!" when I ping to 192.168.1.10,
can anyone help me to figure it out? I will be thankful.
Great article on creating a project for STM32H7 with Ethernet and LwIP stack! The step-by-step instructions and clear explanations make it easy to follow. It's a helpful guide for anyone looking to work with these technologies. Well done!
Hi all,
I am new to STM32 processors and know very little.
I have a Nucleo 144 with STM32F756 processor and my web pages are loading slowly - i.e., they take a few seconds to load.
HTML pages served are only a few kilobytes in size before flattening them with the makefsdata tool.
Otherwise they are working fine.
Is there any tweaks I can do to increase the server page responses?
Thanks in advance.
Abid
I agree this is very helpful.
One remaining problem:
My configuration on a H743 is not working when I follow the example MPU configuration. The MPU setting for the Rx_PoolSection (I'm using the same address 0x30040200 as in the example) is missing. The DMA is reading and writing the buffers in the memory pool and so it must be set to not shareable, not cacheable and not bufferable.
Thanks a lot for sharing... Just following this post and making necessary changes, my STM32H753VI is now capable of sending 86Mbps continuous data thru UDP.
Hi, Adam,
I am referencing you and others posts for the STM32Hx Ethernet issues to try to make my own board to work.
Unfortunately, my board is still not working after about two weeks debugging.
Basically, I am using STM32H723VG with LAN8740 for MII with development tools STM32CubeIde Version 1.11.2 and STM32Cube_FW_H7_V1.11.0 + LWIP without RTOS.
Referencing the posts here, I've made some adjustments for MPU and _Flash.ld.
The Rx Buffer is located at D1(0x2400C000) and set LWIP_RAM_HEAP_POINTER to 0x30000400.
I have tested the hardware interface by verification LAN8740 registers and cable connection indicating that hardware is working since link status and auto-negotiation working properly and Rx and Tx signals are observed once the DHCP is starting. But STM has not received the message from the router since DHCP will be time out.
I've reviewed lots of posts about H7 ethernet issue, but still couldn't figure out what is missing.
Any suggestions will be appreciated.
I've posted some info below for the reference.
Thanks.
Junbo
// MPU setting
.lwip_rx_pool_sec
0x000000002400b740 0x5453 load address 0x0000000008030454
0x000000002400c000 . = ABSOLUTE (0x2400c000)
*fill* 0x000000002400b740 0x8c0
*(.Rx_PoolSection)
.Rx_PoolSection
0x000000002400c000 0x4b93 ./LWIP/Target/ethernetif.o
0x000000002400c000 memp_memory_RX_POOL_base
.lwip_dma_desc_sec
0x0000000030000000 0x2c0 load address 0x0000000008030454
0x0000000030000000 . = ABSOLUTE (0x30000000)
*(.RxDecripSection)
.RxDecripSection
0x0000000030000000 0xc0 ./LWIP/Target/ethernetif.o
0x0000000030000000 DMARxDscrTab
0x0000000030000200 . = ABSOLUTE (0x30000200)
*fill* 0x00000000300000c0 0x140
*(.TxDecripSection)
.TxDecripSection
0x0000000030000200 0xc0 ./LWIP/Target/ethernetif.o
0x0000000030000200 DMATxDscrTab
// DHCP log
Hard Reset PHY LAN8740....
LWIP Init....
netif: added interface st IP
addr
0.0.0.0
netmask
0.0.0.0
gw
0.0.0.0
netif: setting default interface st
Link UP(5)
FULL-DUPLEX(10M)
dhcp_start(netif=0x2400507c) st0
dhcp_start(): mallocing new DHCP client
dhcp_start(): allocated dhcp
dhcp_start(): starting DHCP configuration
udp_bind(ipaddr =
0.0.0.0
, port = 68)
udp_bind: bound to
0.0.0.0
, port 68)
udp_connect: connected to
0.0.0.0
, port 67)
dhcp_discover()
dhcp_create_msg()
transaction id: xid(4bb5f646)
dhcp_discover: making request
dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)
udp_send: added header in given pbuf 0x24009958
udp_send: sending datagram of length 316
udp_send: UDP packet length 316
udp_send: UDP checksum 0xf701
udp_send: ip_output_if (,,,,0x11,)
ip4_output_if: st0
IP header:
+-------------------------------+
| 4 | 5 | 0x00 | 336 | (v, hl, tos, len)
+-------------------------------+
| 0 |000| 0 | (id, flags, offset)
+-------------------------------+
| 255 | 17 | 0xba9d | (ttl, proto, chksum)
+-------------------------------+
| 0 | 0 | 0 | 0 | (src)
+-------------------------------+
| 255 | 255 | 255 | 255 | (dest)
+-------------------------------+
ip4_output_if: call netif->output()
etharp_output()
ethernet_output()
ethernet_output: sending packet 0x24009958
dhcp_discover: deleting()ing
dhcp_discover: SELECTING
dhcp_discover(): set request timeout 2000 msecs
dhcp_fine_tmr(): request timeout
dhcp_timeout()
dhcp_timeout(): restarting discovery
Hello Mr. Adam BERLINGER
Thank you so much for the very helpful article.
I'm making a simple board based on STM32H7 and LAN8720 (currently I don't have LAN8742). I just started using STM32, I follow your tutorial and samples code on github, ping is OK but it disconnects after some time (please see the log below).
Do I need to change any parameters? Please give me some suggestions.
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=2ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=2ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=2ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=3ms TTL=255
Reply from 192.168.1.123: bytes=32 time=7ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=3ms TTL=255
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Reply from 192.168.1.123: bytes=32 time=2ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=3ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=3ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time<1ms TTL=255
Reply from 192.168.1.123: bytes=32 time=1ms TTL=255
Bumping this.
I have the exact issue others are talking about in this thread with the pbuf assert
Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
There is so much conflicting information and so many different memory configurations being discussed on these forums and in the ST code. The information from ST has been extremely hard to follow. For example, why does the memory config from this repo differ from the CubeH7 V1.11?
I am using CubeH7 V1.11.0 with the exact memory layout it recommends:
"
.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30000000);
*(.RxDescripSection)
. = ABSOLUTE(0x30000200);
*(.TxDescripSection)
. = ABSOLUTE(0x30000400);
*(.Rx_PoolSection)
} >RAM_D2
"
@Adam BERLINGER @STOne-32 Can we please get an update with a working setup, which does not have pbuf assert issues, with v1.11? *Have the CubeH7 Stm32H723 examples ever actually been seen to work without memory issues?*
Thanks,
Hello I want to use stm32h747 s ethernet periferal. But ı have to use Rmii and without rtos mode. I gues can you help me??
Dear @arena_chris1seto ,
Our technical teams are working on it right now in the Opened ticket and will be back to you shortly, we need absolutely to replicate the behavior using our environment of board and thank you again for your patience and collaboration to go to the end.
Ciao
STOne-32
Dear all, @HLe.2, @arena_chris1seto
unfortunately when LAN8720 is used in REF_CLK_OUT mode (RMII clocks generated by PHY), the timing is not compatible with STM32H7. In that case the RXD output hold is 1.4ns minimum on PHY side, while STM32H7 requires at least 2ns.
Also the datasheets of LAN8720 warns about this compatibility issue.
Such issue is not present when using LAN8742, or supplying 50MHz RMII clock externally. Also please note that STM32H7 PLL output through MCO (Micro-controller clock output) is not suitable for such signal, due to long-term jitter requirements.
Note: STM32F2/F4 and STM32F7 should be still compatible with LAN8720, since they have different timing constraints than STM32H7. But it is better to double-check the particular device.
Best regards,
Adam Berlinger
Thanks @Adam BERLINGER , yeah I will admit we were caught by this. I'll rework a new RMII reference clock onto the board. Any thoughts on the pbuf issues?
I bought some STM32 Nucleo dev boards to hopefully replicate the issue on official ST hardware with completely unmodified example code.
Hi everyone! I'm excited to see all the comments and questions regarding this article.
However, to prevent bloating the comment section and to give you the best possible guidance to your question, I strongly recommend creating a post in our STM32 MCU forum (click here).
This gives you the best possible opportunity to get the answer you need. We have active members that are happy to answer your questions.
Best regards,
Laurids
Hello everyone,
I know it's been some time since the beginning of the discussion, but the topic is as hot as the first time it was shared.
@IOvch already solved my issues a long time ago, but i couldn't find the uploaded files he talks about in one of his replies. I'm developing the lwip stack on M4 device (stm32H755 nucleo) and it seems to be very tricky, also listening all the relpies and comments, the memory allocation. I have one question especially: is MPU mandatory for M4 config? They are still out of my understanding the definitions of cacheable, bufferable and shareable, could you providwe some documentation about it please?
Thanks in advance
Zaaack
Hello,
It is best to provide IOC files on your next release of the CubeMX update.