cancel
Showing results for 
Search instead for 
Did you mean: 

ETH_DMACSR_RBU error occurs and stalls the Ethernet receive on STM32H7. Is there a way around this issue with the DMA?

Nick1234569
Associate II

Hi,

I've been using the STM32H7 example which uses the new reworked Ethernet driver (https://github.com/STMicroelectronics/STM32CubeH7).

Changed the application layer of the example (LwIP_HTTP_Server_Netconn_RTOS) and during larger transfers, the DMA error (ETH_DMACSR_RBU) occurs and simultaneously Wireshark shows that the communication has issues (retransmissions, tcp window full) and the communication stops for a while.

Code below is located in the ethernetif.c file.

/**
  * @brief  Ethernet DMA transfer error callback
  * @param  heth: ETH handle
  * @retval None
  */
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
{
  SEGGER_RTT_printf(0, "DMA error occurred! %d\n",HAL_ETH_GetDMAError(heth) );
  if((HAL_ETH_GetDMAError(heth) & ETH_DMACSR_RBU) == ETH_DMACSR_RBU)
  {
     SEGGER_RTT_printf(0, "DMA error occurred - releasing semaphore \n");
     osSemaphoreRelease(RxPktSemaphore);
  }
}

Here is the Wireshark picture which shows the issue:

0693W00000KcE0VQAV.png 

How can this be fixed?

It causes the low throughput which is a big problem for our use case.

If this is an issue with the driver, what version to use then?

The important project files are in the attachment.

Can you please give a suggestion on what might be the issue.

Thanks

13 REPLIES 13

You meant ETH_DMACRXDTPR in the last section of your comment, which talks about RBU. And, by the way...

RM0433 Rev 7, "Channel status register (ETH_DMACSR)", page 2924:

Bit 7 RBU: Receive Buffer Unavailable

... To resume processing Rx descriptors, the application should change the ownership of the descriptor and issue a Receive Poll Demand command. If this command is not issued, the Rx process resumes when the next recognized incoming packet is received. ...

So it turns out writing a ETH_DMACRXDTPR is not mandatory. This fact should also be properly documented in the following sections of RM0433 Rev 7:

  1. "58.4.1 DMA controller", "DMA reception", step 11 at page 2813.
  2. "Figure 779. Receive DMA flow", exit of "Supsend Rx DMA" state, page 2814. Also fix the spelling of "Supsend".
  3. "58.9.4 Performing normal receive and transmit operation", step 3, page 2872.

And, of course, the same is true for the respective sections of other H7 reference manuals - RM0399, RM0455, RM0468.

@Imen DAHMEN​, another fix and improvement for the H7 reference manuals.

> multiple of 512 bytes

There is no such requirement. This was "discussed" there and nobody gave any valid explanation:

https://community.st.com/s/question/0D53W00000EGsnUSAT/how-does-ethernet-rx-descriptor-wrapping-work-on-stm32h7

Want to like your reply. But by my testing seems to indicate ETH_DMACRXDTPR must written following RBU.

My method:

  • Dimension 3 rx buffers; because my buffer size is less than MTU and so RBU occurs often.
  • Write 0 to ETH_DMACRXDTPR, in ETH_DMARxDescListInit, which is called by HAL_ETH_Init, and don't write it anywhere else.

My observations:

  • DHCP acquires an address ok.
  • On pinging my device, it replies once or twice then throws "Device unreachable" and its Ethernet rx never recovers.

Whereas if I add writing 0 to ETH_DMACRXDTPR in HAL_ETH_BuildRxDescriptors, when one or more rx buffers have been added the next rx descriptors and their OWN set, the Ethernet rx is continuously reliable (albeit lower performance) with the 3 rx buffers.

My software:

Have you tested "the Rx process resumes when the next recognized incoming packet is received. ..." after RBU without writing ETH_DMACRXDTPR yourself or have any other ideas to share? Thanks

I haven't even touched a H7 part... But I have tested the same functionality on F7. I commented out the Rx poll demand code and configured the Rx with a single buffer of 1536 B size. On a pretty silent network I run an Iperf2 test from a PC and was pleasantly surprised that it still managed to pull off a full wire speed. Of course, when I started pinging once per second in parallel, the Iperf2 speed dropped drastically, it was dropping connections and about a third of pings also failed. When any of these processes was stopped, the other one returned to normal functioning. Of course, all of that was done without a restart or network changes.

So it works on F7 and most likely also on F4, F2, F1. It should be noted that for those parts it is properly documented in the respective reference manuals. Anyway the reference manuals for H7 parts must be fixed either by adding a decent descriptions or by removing the irrelevant one.