TCP/IP Hard Fault on FreeRTOSconnect

I am trying to connect my STM32F7 to my Rust desktop application, but I’m having issues with it connecting. Specifically, I encounter a Hard Fault error when I enter the FreeRTOS_connect function.

I have confirmed that my Desktop application works by writing a client program in Python.

I have stepped through my program, and it will always reach the xEventGroupWaitBits function call in FreeRTOS_connect. Once it reaches uxTaskResetEventItemValue() in xEventGroupWaitBits(), there is always a Hard Fault error. Sometimes, however, it will never get to that function, and a Hard Fault will still occur.

Are there any ideas to assist with my problem?

My concern and the reason I am reaching out is that I feel like it shouldn’t even be reaching these function calls, as the FreeRTOS_connect() function passes various sleep checks before it reaches xEventGroupWaitBits().

I have attached my source file where I replicate aspects of the Tutorial functions. These are the functions I call in my main task.

TCP_IP.c (6.8 KB)

Hi bsgursta,

Thanks for you interest in using FreeRTOS+TCP.

Have you checked your heap function, does it work properly?
Which heap_?.c module do you use?
Do you get a clear warning/assert when pvPortMalloc() fails?

Is ICMP/ping enabled? Can you ping your STM32F7?

Can you ping from your STM32F7 to your server at 10.x.x.x?

Here I see a minor typo:

     /*connect to remote socket */
-    if( FreeRTOS_connect( xSocket, &xRemoteAddress, ( sizeof( xRemoteAddress ) == 0 ) ) )
+    if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
     {
         SEGGER_RTT_printf( 0, "Connected\n" );

The above is no problem because xAddressLength is ignored inside FreeRTOS_connect().

The following code needs a change:

    xBytesSent = FreeRTOS_send( xSocket, pcBuffer, xLen, flags );
    
    if( xBytesSent <= 0 )
    {
        xAlreadyTransmitted += xBytesSent;
    }
    else
    {
    	printf( "Bytes not send" );
    }

The return value of FreeRTOS_send() is as follows:

>0 : the number of bytes sent
= 0 : zero bytes have been sent, no error
< 0 : -EINVAL, -ENOMEM, -ENOTCONN, -EINTR, -EWOULDBLOCK.

Please note that EINTR and EWOULDBLOCK are non-fatal error.

You can find the errno declarations in frertos/include/projdefs.h

Are you sure that you want to pass a pointer to a socket (which is a pointer)?

Later when calling recv(), you forget to de-reference the pointer in FreeRTOS_recv(socket_closing, ...).

void vshutdownSocket(Socket_t *socket_closing, char *pcTxBuffer, const size_t xTotalLengthToSend )
{
    ...
    //check if the shutdown is happening
    if(shutdown){
        FreeRTOS_closesocket(*socket_closing);
        printf("socket shutdown");
    }
    else{
        printf("socket not shutdown");
    }

I think that a function called vshutdownSocket() should promise to always close the socket, and thus free the memory space.

Calling shutdown makes sure that the closure of the connection is initiated. It is started by sending the FIN flag. When acknowledged, the socket may be destroyed by calling closesocket().

When a recv() function returns an error, it is useless to call shutdown and wait for an acknowledge.

“Gracefully” shutting down a socket is not an obligation, although it has many advantages. It makes sure that the peer also closes the socket, thus freeing space. Think of an HTTP server with limited resources.

Before shutting down the TCP connection, I would normally change the socket’s RX timeout (making it small, e.g. 10 ms), and not call vTaskDelay(). Calling FreeRTOS_recv() will already do a delay.

Next steps:

Although it might not solve your hard-fault, could you make the proposed changes?

I can see that FreeRTOS_connect() is called by vSendTCP(), but can you show how vSendTCP() is called?
Where does ConfigTCPClientSocket() come in?

Cheers

One more tip: make sure that the task calling vSendTCP() has enough stack space.

You can use configCHECK_FOR_STACK_OVERFLOW, or check ‘manually’ how much stack space is used/needed.

For instance can you check where the memory block pcTxBuffer is declared: stack, static or heap?

Hi @bsgursta, did you get any further with this issue?