Skip to main content
Visitor II
July 17, 2025
Question

STM32H743 ETH Problem with RT Thread and LWIP

  • July 17, 2025
  • 3 replies
  • 681 views

Hi,I created the STM32H743 project based on RT Thread and LWIP, only open ICache, if I modify the content of a function, it will lead to the Ethernet transmission success, but there is no data on the MII interface, debugging compared the ETH register under normal communication and the ETH register under abnormal condition. The configuration is the same; Dynamically allocated memory is placed on 0x24000000, and Ethernet descriptors and received data are placed on 0x30040000.
In the above case, through multiple tests, it was found that increasing the size of the function block can restore the sending of ETH to normal, such as adding multiple __nop instructions.
Why this is the case, and what to look out for if you want to open only ICahe or DCache.

static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
	uint32_t i=0;
 struct pbuf *q;
	err_t errval = ERR_OK;
	static ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
	memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));

	for(q = p; q != NULL; q = q->next)
	{
		if(i >= ETH_TX_DESC_CNT)
		 return ERR_IF;
 rt_memcpy(Tx_Buff[i],q->payload,q->len);
		Txbuffer[i].buffer = Tx_Buff[i];
		Txbuffer[i].len = q->len;

		if(i>0)
		{
		 Txbuffer[i-1].next = &Txbuffer[i];
		}

		if(q->next == NULL)
		{
		 Txbuffer[i].next = NULL;
		}

		i++;
	}

	TxConfig.Length = p->tot_len;
	TxConfig.TxBuffer = Txbuffer;
	HAL_ETH_Transmit_IT(&heth, &TxConfig);
	return errval;
}

The above code is LWIP call ETH send.

uint16_t DW3000GetPOA(dwt_sts_mode_e sts_mode)
{
 uint16_t poa_value = 0;
 dwt_rxdiag_t poa_rx_diag;
 dwt_readdiagnostics(&poa_rx_diag);
 if(sts_mode == DWT_STS_MODE_OFF)
 {
 poa_value = poa_rx_diag.ipatovPOA;
 }
 else if((sts_mode & 0x0f) == DWT_STS_MODE_1)
 {
 poa_value = poa_rx_diag.stsPOA;
 }
 else if((sts_mode & 0x0f) == DWT_STS_MODE_2)
 {
 poa_value = poa_rx_diag.sts2POA;
 } 
 else
 {
 poa_value = poa_rx_diag.ipatovPOA;
 } 
// if((poa_value&0x2000) != 0) 
// {
// poa_value |= 0xc000;
// } 

 return poa_value;
}

The above is the function that causes an Ethernet exception.

 

    This topic has been closed for replies.

    3 replies

    Super User
    July 17, 2025

    What is dwt_readdiagnostics() ? Does it tinker with the Cortex-M DWT?

     

    ketlenAuthor
    Visitor II
    July 18, 2025

    dwt_readdiagnostics() is the SDK interface provided by Qorvo for the DW3210 chip, which uses SPI for communication.

    Graduate
    July 21, 2025

    Hi Ketlen,
    That's very likely an issue due to enabling the caches. We have experienced it as well.

    May I ask you 2 questions:
    1. Are RT-Thread and lwIP fixed requirements for your project?
    2. Is there a reason for wanting to keep the I-Cache or D-Cache on?

    Honestly, from our experience working on the Mongoose Networking library, the best way to deal with Ethernet drivers on chips like the H7 is to disable the caches entirely. Also, we don't mess with MPU regions. We just allocate the descriptors and ETH buffers statically in the same region as all the other variables. We noticed the tiny performance hit is nothing compared to all problems caching caused to our Ethernet drivers.

    ketlenAuthor
    Visitor II
    August 6, 2025

    The problem has been identified. When using the STM32H7, I reduced the main frequency to 160 MHz, and for the HPRE division, I chose 1. As a result, the peripheral clock is also 160 MHz. As shown in the following figure:

    ketlen_0-1754477794195.png

    The CubeMX project mentioned above uses an older version of the HAL. If the new HAL library is used, CubeMX will automatically generate an error message, as shown in the following figure:

    ketlen_1-1754477909575.png

    After verification, it was found that if the HPRE frequency division is set to 2 or higher, all Ethernet functions operate normally.

    But I still don't understand why. According to the instructions on CubeMX, the maximum peripheral clock can be set to 240 MHz. The 160 MHz I have set here should be within the valid range.

    Super User
    August 7, 2025

    The 160 MHz I have set here should be within the valid range.

    As the picture shows, in your situation the APB1/2/3 inputs are out of limits (120 MHz max.)

    PavelA_0-1754592555128.png

     

    ketlenAuthor
    Visitor II
    August 8, 2025

    ketlen_0-1754623594399.png

    This is the configuration I used. I set the HPRE pre-frequency division to 1. After turning off the Cache, the program could not run normally, but when the Cache was turned on, it could run normally. If I set the HPRE pre-frequency division to 2, the switch of the Cache had no effect on the program's operation. However, after turning on the Cache and making the relevant modifications mentioned in the previous problem regarding dw3000, the problem of Ethernet unable to send data still existed. Later tests revealed that the delay time of Flash during RCC initialization affected the sending of Ethernet. If as shown in the following figure:

    ketlen_1-1754624091037.png

    If I change FLASH_LATENCY_1 to FLASH_LATENCY_2, and with the Cache enabled, the Ethernet can function normally for data transmission.