cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 ETH Problem with RT Thread and LWIP

ketlen
Associate II

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.

 

5 REPLIES 5
Pavel A.
Super User

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

 

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

MStackDev_376
Associate II

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.

In the abnormal case, after Ethernet transmission is completed, a delay is added, Ethernet can complete transmission, but wireshake can not catch Ethernet data; If we modify the DW3000GetPOA function by adding more than four __nop functions or adding expressions like i++, we can fix the problem. The map shows that the address of the DW3000GetPOA function remains the same, and the functions following the dw3000getpoa function are moved a few bytes back. This movement allows HAL_ETH_Transmit_IT to send the data out, in which case wireshake can catch the Ethernet data.

The following figure shows the memory contents of the Ethernet send buffer in the exception case:

ketlen_0-1753344279842.png

The following figure shows the register values of the Ethernet MAC part in the abnormal case:

 

ketlen_5-1753344551579.png

 

ketlen_3-1753344463341.pngketlen_4-1753344476197.png

 

The MAC registers are configured identically to the normal MAC registers, except that they cannot send data.

ketlen
Associate II

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.