MSP432 FreeRTOS+TCP Zero Copy Issues

So I think my issue is similar to the one discussed with the title: STM32H743 FreeRTOS+TCP issue with ZERO Copy (apparently I can’t create a link to the discussion?), but thought I’d ask anyway, as I’m running on an MSP432 which might introduce/change some of the issues.

I’ve successfully integrated the +TCP libraries into my project, and seem to have a fairly stable stack. My project was started and developed with ipconfigZERO_COPY_TX_DRIVER set to 0.

However, during testing my project almost always eventually fails, and seems to fail at the following location:

Line 838 of MSP432E4NetworkInterface.c, in xNetworkInterfaceOutput():

/* When the following assert is hit, please make sure that
 * ipconfigZERO_COPY_TX_DRIVER is defined as '1' in your
 * FreeRTOSIPConfig.h header file. */
 configASSERT(xReleaseAfterSend != pdFALSE)

What’s weird is that it usually takes several hours/million packets to get to the point where it fails at this assert. So I’m not sure why it takes so long to achieve the fail condition, or what’s changing. We’re not actively processing any received packets, and there shouldn’t be any traffic directed at us on the network, although we do have an open receive socket, as we’d like the ability to receive and process some packets in the future. At this point we’re purely creating and sending packets, and we’re able to send millions before this occurs. Both sockets (send & receive) are configured as UDP with FREE_RTOS_SOCK_DGRAM & FREERTOS_IPPROTO_UDP used during the FreeRTOS_socket() call.

My call stack shows the following:

xNetworkInterfaceOutput() @ MSP432ENetworkInterface.c : 838
prvTCPReturnPacket() @ FreeRTOS_TCP_Transmission.c : 536
prvTCPSendSpecialPacketHelper() @ FreeRTOS_TCP_Transmission.c:1475
prvTCPSendReset() @ FreeRTOS_TCP_Transmission.c:1505
xProcessReceivedTCPPacket() @ FreeRTOS_TCP_IP.c:686
...

So I’m not sure why we’re calling TCPSendReset(), or what the purpose of TCPSendSpecialPacketHelper() is - I’m actually a bit confused as why we would need to reset anything, given that both our sockets should be UDP, so there shouldn’t be any connection to reset?

Anyway, in complying with the rest above the assert, I set ipconfigZERO_COPY_TX_DRIVER to 1. I also updated my calls to
FreeRTOS_sendto() to include the FREERTOS_ZERO_COPY flag.

When doing this, my project compiles and runs, and produces absolutely no ethernet traffic, despite FreeRTOS_sendto() returning the appropriate size for bytes sent.

In looking at the discussion referenced, the first thing that stands out to me is my use of Bufferallocation_2.c instead of Bufferallocation_1.c, so that’s near the top of the list to try.

I’m curious if anyone has any other thoughts on what might be going on, either with the eventual stoppage when not using Zero Copy, or with the lack of packets entirely while using Zero Copy.

Thanks,
Ian

Reading your description of your application, this should not happen. Is it possible for you to capture network traffic?

Are you doing the same thing described in this thread and does the solution apply to you as well - STM32H743 FreeRTOS+TCP issue with ZERO Copy, this time UDP - #22 by arijav

I don’t think I’m implementing my system the way that post originally described (i.e. trying to allocate the buffer once.) We allocate for every packet we send, and assume the packet is freed by the network code unless the send fails, in which case we free the buffer ourselves when handling the send error.

Edit: The above applies when attempting to implement the Zero Copy scheme. However, even when doing so, the system still fails to actually produce packets on the network.

I’ve been trying to capture the network traffic that surrounds the issue, but so far no real success. Mostly because the system doesn’t want to fail when I’m actually monitoring it. My guess is that there’s some outside traffic that’s being accepted by our stack that causes our system to fail, and when we don’t see that traffic, the system runs just fine. But since I don’t know WHAT that traffic is, I don’t know how to force it to happen.

Edit: Testing and capturing of the network packets occur when NOT implementing Zero Copy, as that’s the only way we can actually get traffic on the network from our system. And it seems like there’s no reason we should NEED to use Zero Copy, so if I can figure out why the system crashes occasionally when not using Zero Copy, maybe I can figure out how to fix it.

Are you running it in the debugger? Do you get any call stack when you crash?

Hello Ian,

About FREERTOS_ZERO_COPY: it is a flag that works at the API side: recvfrom() and sendto(). When using it you save one call to memcpy(). You can even reply using the same buffer, provided that the size of the buffer is big enough to contain the answer ( or use BufferAllocation_1.c because then the allocated size is always equal to the MTU ).

There is a good description with examples about sendto(), and about recvfrom(). Did you do the same steps?

ipconfigZERO_COPY_TX_DRIVER ( and ipconfigZERO_COPY_TX_DRIVER ) work at the other end: when passing network packets to the DMA, either for transmission or for reception.

Using zero-copy at TX means that a buffer is passed to DMA, and the transmission may go on after the function xNetworkInterfaceOutput() has returned. Therefor, the driver must have the ownership ( xReleaseAfterSend ) of the network buffer.

If I were you, I would make the following 2 simple changes:

● Remove the configASSERT, and in stead dump an outgoing packet:

-    configASSERT( xReleaseAfterSend != pdFALSE );
+    if( xReleaseAfterSend == pdFALSE )
+    {
+        FreeRTOS_lprintf( ( "xReleaseAfterSend was false\n" ) );
+        return;
+    }

● If you only use UDP, you don’t need to include the TCP-code, so define in your FreeRTOSIPConfig.h the following:

#define  ipconfigUSE_TCP   0

As long as ipconfigUSE_TCP is defined as 1, it is normal that prvTCPSendReset() gets triggered by an incoming TCP packet. A TCP device must reply with a RST to erroneous incoming TCP-packets.

E.g. when you try to connect to your device with telnet, you will see RST packets.

PS. What is the value of your ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, i.e. how many network buffers did you define? Or can you attach the FreeRTOSIPConfig.h that you use?

When you define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES = 1, your driver is supposed to filter out unwanted packets.

You can see an example of such a filter in the STM32Fx driver. It is good to filter packets as early as possible. So when ipconfigUSE_TCP is disabled, a filter could drop all TCP packets.

Hello Ian, did you make any progress on this?

Hein