Porting FreeRTOS-PLUS-TCP on STM32F207VG

nonameletters wrote on Wednesday, August 15, 2018:

Hello, I am porting FreeRTOS-PLUS-TCP and testing it on NUCLEO board with STM32F207ZGT6. I generate project with CubeMX with FreeRTOS support, then add sources for TCP from FreeRTOS 10.0.0 downloaded files. I achived next results:

  • ping test goes well
  • I created Server thread and I can receive GET request
    Problem is that when I trying to send the responce using FreeRTOS_send(…), nothing happens. I checked this by wireshark. No packets from NUCLEO board.
    What should I check? Some thoughts?

heinbali01 wrote on Wednesday, August 15, 2018:

Ping goes well, that means that your +TCP port is able to send packets.
Now you receive a GET request, and the answer to it never arrives?

Is that your own code which receives the GET request? If so, could you show it?

Maybe you could do a simpler test: just create a telnet server socket?

nonameletters wrote on Thursday, August 16, 2018:

//
void vCreateTCPServerSocket(void *args)
{
static uint8_t page[] = "



My First Heading



My first paragraph.




";
BaseType_t lByteReceived = 0, lByteSended = 0;
xListeningSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);

configASSERT(xListeningSocket != FREERTOS_INVALID_SOCKET);

FreeRTOS_setsockopt(xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeout, sizeof(xReceiveTimeout));


xBindAddress.sin_port = ( uint16_t ) 80;
xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );

FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );
FreeRTOS_listen( xListeningSocket, 20 );

//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
for( ;; )
 {
     /* Wait for incoming connections. */
	 // HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
     xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
     FreeRTOS_setsockopt(xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeout, sizeof(xReceiveTimeout));
     if (xConnectedSocket != FREERTOS_INVALID_SOCKET )
     {
    	 lByteReceived = FreeRTOS_recv(xConnectedSocket, socketRecvBuf, sizeof(socketRecvBuf), 0);
    	 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
    	 //printf("Bytes received: %d\n", lByteReceived);
    	 //printf("%s\n", socketRecvBuf);
    	 if (lByteReceived > 0)
    	 {
    		 lByteSended = FreeRTOS_send(xConnectedSocket, page, sizeof(page), 0);
    		 printf("Bytes sended: %d\n", lByteSended);
    		 vTaskDelay(pdMS_TO_TICKS(4));
    	 }
     }
     // HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);

 }

}

Doing this I reeive GET lByteReceived = FreeRTOS_recv(xConnectedSocket, socketRecvBuf, sizeof(socketRecvBuf), 0);
Printf shows me correct request.
But FreeRTOS_send do nothing. Watching by wireshark i se no response.
Some thoughts?

heinbali01 wrote on Thursday, August 16, 2018:

You are setting the send time-out on xConnectedSocket, but you do not show the actual value of xSendTimeout.
Despite that, I can not see an apparent reason why FreeRTOS_send() would not send-out the data contained in the variable page.

Have you defined ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM as 0?
If it is non-zero, either your network driver must calculate and set the checksums ( IP and protocol ), or the EMAC must set it.

Your application is likely to run until all resources are exhausted: after sending the data, the variable xConnectedSocket will be overwritten and the handle to the old socket becomes unreachable.

If you want to keep it simpler ( for testing ), allow only a single client:

    FreeRTOS_listen( xListeningSocket, 1 );

And keep on reading from xConnectedSocket until you get a negative value, not equal to -EWOULDBLOCK:

    if( xConnectedSocket != FREERTOS_INVALID_SOCKET )
    {
        for( ;; )
        {
    
            lByteReceived = FreeRTOS_recv( xConnectedSocket, socketRecvBuf, sizeof(socketRecvBuf), 0 );
            if( ( lByteReceived < 0 ) && ( lByteReceived != -pdFREERTOS_ERRNO_EWOULDBLOCK ) )
            {
                /* Break out of the loop in order to receive a new client. */
                /* The most probable return code is -pdFREERTOS_ERRNO_ENOTCONN */
                break;
            }
            if( lByteReceived > 0 )
            {
                /* Send a reply back. */
                lBytesSent = FreeRTOS_send(xConnectedSocket, page, sizeof(page), 0);
                printf( "Bytes sended: %d\n", lBytesSent );
                if( ( lBytesSent < 0 ) && ( lBytesSent != -pdFREERTOS_ERRNO_EWOULDBLOCK ) )
                {
                    /* Send returns a fatal error, break from the loop. */
                    break;
                }
            }
        }
        FreeRTOS_closesocket( xConnectedSocket );
        xConnectedSocket = FREERTOS_INVALID_SOCKET;
    }

You set FREERTOS_SO_RCVTIMEO of the listening socket. That value will be inherited by the child socket.
Give it a reasonable value unequal to zero.

If you want to see a simple HTTP server that works well, please download :

https://freertos.org/FreeRTOS-Labs/downloads/160919_FreeRTOS_Labs.zip?dl=0

and have a look at FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\protocols\

nonameletters wrote on Thursday, August 16, 2018:

Thanks a lot. xSendTimeout is set to portMAX_DELAY. ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM is not defined by me. Many thanks. Now I go to check.

heinbali01 wrote on Thursday, August 16, 2018:

Does FreeRTOS_send() return the length of page?

It would be nice if you can set a breakpoint before calling FreeRTOS_send(). When that hits, set a breakpoint in xNetworkInterfaceOutput() to see what data are actually put on the wire.

nonameletters wrote on Thursday, August 16, 2018:

FreeRTOS_send() returns the exact length of page. I set breakpoint in xNetworkInterfaceOutput(), it dosn’t calls. It calls in other cases but after FreeRTOS_send() it don’t

heinbali01 wrote on Thursday, August 16, 2018:

HI Vlanov, as you are developing a port, it is maybe better, easier, if you contact me directly. Please write an email to “hein [at] htibosch [dot] net”. Thanks