FreeRTOS 10.1.1 HTTP server on SAM4E Xplained stops after sending one file

I like the mutex idea, but I feel like there’s a performance impact when you are sending a lot of packets at the same time. It seems like this problem goes away if you increase the number of descriptors, which tells me that you can send multiple packets at the same time.

Here’s the code though, any changes that I made I try to put a “//!!!” in-line comment.
FreeRTOS_Plus Portable.zip (25.3 KB)

That is an interesting solution, it also works for me. It is 3 percent faster than my solution with the extra mutex.

It looks like a silicon problem: as soon as the CPU fills all transmission descriptors , the peripheral “forgets” to call the transmit-complete-interrupt GMAC_ISR_TCOMP.

Solution:

When there are GMAC_TX_BUFFERS descriptors, we will make sure that there is always one descriptor free. That seems to do the trick.

The counting semaphore xTXDescriptorSemaphore will have a maximum count of GMAC_TX_BUFFERS-1.

While testing I saw that sometimes 2 TX descriptors were occupied, and both transmissions were completed with a GMAC_ISR_TCOMP interrupt.

I cleaned the sources and uploaded them to my branch IPv4_single_SAM_EMAC_race_condition.

Note that for the SAME70, we don’t have to calculate the checksum for transmission. Not calling vGMACGenerateChecksum() makes sending a lot faster.

Testing:

  • I tested both GMAC_TX_BUFFERS=2 and 6.
  • Also I varied the ipconfigNETWORK_MTU, between 586 and 1500.

Optimal settings for a IPERF3 TCP test:

#define GMAC_RX_BUFFERS                           4
#define GMAC_TX_BUFFERS                           6
#define ipconfigNETWORK_MTU                    1500
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS   24
#define ipconfigIPERF_TX_BUFSIZE  ( 6 * ipconfigTCP_MSS )	/* Units of bytes. */
#define ipconfigIPERF_TX_WINSIZE  ( 4 )			/* Size in units of MSS */
#define ipconfigIPERF_RX_BUFSIZE  ( 6 * ipconfigTCP_MSS )	/* Units of bytes. */
#define ipconfigIPERF_RX_WINSIZE  ( 4 );			/* Size in units of MSS */

Would you be so kind to test the above driver from Github?
I will also keep my test with IPERF running here and transmit 1 TB :slight_smile:

1 Like

I tried the latest code from your branch and I wasn’t able to break it.

Just a small bug/suggestion. Inside xNetworkInterfaceOutput() right after gmac_dev_write() gets called there is a configASSERT(). The bug is that there is a semicolon missing. I have never hit this assertion, but I was wondering if it’s even a good idea to have an assertion right there. I was thinking that it might be better to increment some (new?) member in the STransmitStats struct for diagnosis, release the semaphore, do any more clean-up work, and keep on chugging? The packet will get lost but the processor won’t hang. Thoughts?

@Maty wrote:

there is a configASSERT() . The bug is that there is a semicolon missing

I replaced the configASSERT() with the following action:

if( ulResult != GMAC_OK )
{
    TX_STAT_INCREMENT( tx_write_fail );
}

I turned the proposed changes into PR #567, which is already merged into FreeRTOS:main.

I keep on running the test between SAME70 and my laptop. It has send 360 GBytes now.

Thanks a lot @Maty for your corporation on this project.

1 Like

Thank you very much for your time on this as well!