Hi
I tried implementing FREE RTOS + TCP on renesas RA6M3 development board.
The process which i am following is
- DHCP assigns the IP address to my board.
- Therafter I opened a socket and binded it with a port number and installed a callback function using setsockopt() function forn connection handling.
- Then I set the socket in listen mode and wait for incoming connections.
I called the TCP_Server_Task() after the DHCP assigns the IP address to the development board.
The issue which i am facing is when i initiate a connection request from my pc to the development board the breakpoint does not hits at the callback function where it accepts the incoming connection.
I have attached the code for the same.
typedef enum
{
Callback_Connect_Disconnect = 0, /* Connect or disconnect */
Callback_Receive /* Data Receive State */
} connectionState_t;
typedef struct
{
Socket_t xSocket;
uint8_t is_Connected;
}Tcp_Socket_t;
typedef struct
{
Socket_t xSocket;
uint8_t *pData;
uint32_t xLength;
}Receive_t;
typedef struct
{
uint8_t type;
Tcp_Socket_t Connect_Disconnect;
Receive_t Receive;
}Callback_Message_t;
static void Callback_OnConnectDisconnect ( Socket_t xSocket, BaseType_t ulConnected )
{
Callback_Message_t Callback_Message;
Callback_Message.type = Callback_Connect_Disconnect;
Callback_Message.Connect_Disconnect.xSocket = xSocket;
Callback_Message.Connect_Disconnect.is_Connected = 1u;
if ( xQueueSend ( xQueue_Callback, (void*) &Callback_Message, 0 ) != pdPASS )
/* In case there is no space in the Queue,
* we should print something to the service port but we are inside FreeRTOS IP so it's better just increment a counter.
* The printing will take place in the main loop.
*/
xQueue_Callback_Errors++;
}
static BaseType_t Callback_OnReceive ( Socket_t xSocket, void * pData, size_t xLength )
{
Callback_Message_t Callback_Message;
Callback_Message.type = Callback_Receive;
Callback_Message.Receive.xSocket = xSocket;
Callback_Message.Receive.pData = pData;
Callback_Message.Receive.xLength = xLength;
static uint8_t Data [1000];
int32_t receivedData;
receivedData = FreeRTOS_recv ( Callback_Message.Receive.xSocket, Data/*pvBuffer*/, sizeof(Data)/*xBufferLength*/, 0/*xFlags*/ );
if ( xQueueSend ( xQueue_Callback, (void*) &Callback_Message, 0 ) != pdPASS )
/* In case there is no space in the Queue,
* we should print something to the service port but we are inside FreeRTOS IP so it's better just increment a counter.
* The printing will take place in the main loop.
*/
xQueue_Callback_Errors++;
return 1;
}
void TCP_Server_Task ( void *pvParameters )
{
//Socket_t IPaccept_Socket, IPreceiver_Socket;
//struct freertos_sockaddr xClient, xBindAddress;
const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 20000 );
//const TickType_t xZeroTimeOut = 0;
const BaseType_t xBacklog = 20;
socklen_t xSize = sizeof (struct freertos_sockaddr);
F_TCP_UDP_Handler_t Handler_OnConnectDisconnect;
/* Create a queue capable of containing 10 callback messages. */
xQueue_Callback = xQueueCreate ( 10, sizeof(Callback_Message_t) );
IPaccept_Socket = FreeRTOS_socket ( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
if ( IPaccept_Socket == NULL )
{
APP_PRINT ( "ERROR - task_IPaccept[] - FreeRTOS_socket failed" );
}
/* Set the listening port to 5050. */
xBindAddress.sin_port = ( uint16_t ) 5050;
xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );
xBindAddress.sin_addr = FreeRTOS_GetIPAddress();
/* Bind the socket to the port that the client RTOS task will send to. */
if( FreeRTOS_bind( IPaccept_Socket, &xBindAddress, sizeof( xBindAddress ) ) == -1 )
{
FreeRTOS_closesocket( IPaccept_Socket );
IPaccept_Socket = FREERTOS_INVALID_SOCKET;
}
/* Set the socket into a listening state so it can accept connections.
The maximum number of simultaneous connections is limited to 20. */
Handler_OnConnectDisconnect.pxOnTCPConnected = Callback_OnConnectDisconnect;
FreeRTOS_setsockopt (IPaccept_Socket, 0, FREERTOS_SO_TCP_CONN_HANDLER, (void *) &Handler_OnConnectDisconnect, sizeof(Handler_OnConnectDisconnect) );
FreeRTOS_listen( IPaccept_Socket, xBacklog );
//Callback_OnConnectDisconnect ( IPaccept_Socket, 0 );
//IPconnections_Initialise();
for (;;)
{
//Callback_Message_t Callback_Message_Queue;
if ( xQueue_Callback_Errors != xQueue_Callback_Errors_prev )
{
APP_PRINT ( "WARNING - task_IPreceiver[] - xQueue_Callback_Errors %d", xQueue_Callback_Errors );
xQueue_Callback_Errors_prev = xQueue_Callback_Errors;
}
if ( xQueueReceive ( xQueue_Callback, &Callback_Message_Queue, portMAX_DELAY ) )
{
switch ( Callback_Message_Queue.type )
{
case Callback_Connect_Disconnect:
{
F_TCP_UDP_Handler_t Handler_OnReceive;
if(Callback_Message_Queue.Connect_Disconnect.is_Connected)
{
IPreceiver_Socket = FreeRTOS_accept ( IPaccept_Socket, &xClient, &xSize );
APP_PRINT ( "Connection accepted %d", IPreceiver_Socket );
/* Install a callback for receiving TCP data. */
Handler_OnReceive.pxOnTCPReceive = Callback_OnReceive;
FreeRTOS_setsockopt ( IPreceiver_Socket, 0, FREERTOS_SO_TCP_CONN_HANDLER, (void *) &Handler_OnReceive, sizeof(Handler_OnReceive) );
}
else
{
FreeRTOS_closesocket ( Callback_Message_Queue.Connect_Disconnect.xSocket );
APP_PRINT ( "Connection closed %d", Callback_Message_Queue.Connect_Disconnect.xSocket );
}
}break;
case Callback_Receive:
{
static uint8_t Data [1000];
int32_t receivedData;
receivedData = FreeRTOS_recv ( Callback_Message_Queue.Receive.xSocket, Data/*pvBuffer*/, sizeof(Data)/*xBufferLength*/, 0/*xFlags*/ );
APP_PRINT ( "Callback_Receive Callback_Message.Receive.xSocket %d Callback_Message.Receive.xLength %d receivedData %d",
Callback_Message_Queue.Receive.xSocket, Callback_Message_Queue.Receive.xLength, receivedData );
}break;
default:
{
APP_PRINT( "Queue Empty" );
}
break;
}
}
}
}
Regards
Sudhanshu Shekhar