2025-04-15 5:56 PM
Not a bug as such, but a nuisance none the less, and likely to catch out those less familiar with the quirks of H7 Ethernet MAC DMA...
If you set up Ethernet and LwIP the way that is recommended (and partially done by STM32CubeMX), with the Ethernet transmit and receive descriptors, receive buffer and LwIP memory pools within Ethernet DMA reachable RAM (RAM D2, 0x30000000 ...), then for the most everything sort of works.
If you use the LwIP sockets API, then it also works as the sockets API copies data to be sent on a socket into LwIP buffers, ensuring that data is in Ethernet DMA reachable memory.
BUT, if you use the netconn API, which is much faster and lighter weight than the sockets API, functions like netconn_write do not copy socket send data. It makes it all the way to the Ethernet driver as zero copy, which is nice. Unfortunately, it is likely that the sent data is on the stack of the calling process, or the general heap. Which makes it non DMA reachable for the Ethernet.
This results in an Ethernet DMA error, Ethernet is disabled and no longer works.
As a minimum, a really nice improvement to the driver would be to check the memory range of the transmit data is Ethernet DMA reachable and assert. At least that way you could understand what you have done and save hours of debugging.
A better improvement would be to copy the memory at that point into a LwIP buffer before calling Ethernet transmit. It is a LwIP driver, so no harm there. Much better solution than having to do it all through user code. And generally only the user part of the pbuf is not already in the right RAM.
2025-04-15 6:33 PM
> As a minimum, a really nice improvement to the driver would be to check the memory range of the transmit data is Ethernet DMA reachable and assert
Good idea. Low level output function in ethernetif.c can check the addresses and assert. Copying requires more thought and management of TX buffer memory.
2025-04-15 6:44 PM
Copying is not too difficult I dont think. It already loops through the pbuf chain creating a matching tx buffer set. If it discovers that a pbuf is pointing to out of range RAM, can allocate a new pbuf, and copy that data into it, and point the tx buffer at that one instead. Of course need to keep track of the pbufs created so can free them, but that could be done by chaining them as they are created, so only one free is required.
There is a risk of an allocation failure of course...
pbufs are guaranteed to be allocated in DMA reachable RAM if LwIP memory has been put in the correct region as is required for zero copy receive buffers. And as per all the examples and STM32CubeMX.
2025-04-15 7:14 PM
Yes, chaining pbufs is a clever trick!