I'm facing a problem with my custom board with LPC1768 MCU. I'm using Ethernet and lwip stack.
It works well many times, but now always.
I'm studying the module lpc17xx_40xx_emac.c and I found something strange. We have a number of TX descriptors configured by the preprocessor symbol LPC_NUM_BUFF_TXDESCS. Suppose it is 4. Now we have two integers, consumer and producer index (cidx and pidx). They both start at zero.
When the application produces a new frame, producer index is incremented in lpc_low_level_output().
When a frame is completely transmitted, the consumer index is automatically incremented by the MCU hw.
In lpc_low_level_output(), lpc_tx_ready() is called to read the number of free TX descriptors available. lpc_tx_ready() returns a number in the range 0..3, even if we have 4 descriptors. I think this is correct, because we can't fill all the descriptors, otherwise the wrap-around of indexes results in mathematical errors when calculating the number of free descriptors (it's a classical problem of ring buffer). We need to loose one descriptor.
At the beginning (cidx=pidx=0) it returns 3 free descriptors.
lpc_low_level_output() blocks if there aren't free descriptors (if lpc_tx_ready() returns 0). Theorically I could call lpc_low_level_output() 100 times without problems: the function blocks until previously added descriptors are serialized out on the wire.
However it seems a wrong behaviour to me. We have to call lpc_tx_reclaim() in order to free the pbufs after they are transmitted.
If the application calls lpc_low_level_output() many consecutive times without calling lpc_tx_reclaim(), it will be able to transmit the data with success (by blocking), but we finally could have some not-freed pbufs in memory.
Indeed lpc_low_level_output() saves the pbufs references in lpc_enetif->txb array, using the produce index as the array index. Here we could overwrite previous pbufs that are really sent but not freed.
In my application I'm facing a similar problem. The application (MQTT client over mbedTLS session) sends some data during TLS handshake. I noticed that under certain conditions, some pbufs aren't completely freed and remains in the heap. It seems this happen when many output packets are produced in short time.
I don't think the application is buggy. I can compile the same code with mingw in a Windows desktop machine and it works well. The only thing that changes is the Ethernet driver. The application and TCP/IP stack is identical.