ModusToolbox 2.2 AnyCloud TCP Server cy_socket_recv() Delay

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JoCh_1493306
Level 3
Level 3
25 sign-ins 10 replies posted 10 questions asked

Hi,

I am testing the AnyCloud TCP Server example project for CY8CPROTO-062-4343W. Inside the tcp_receive_msg_handler(cy_socket_t socket_handle, void *arg) function (I pasted it below), I found that there was about <1s delay when calling the API cy_socket_recv(). I toggled the user LED right before and after calling this API and I found that the delay of calling this function was quite significant. The tcp_receive_msg_handler is called whenever it receives some messages from the TCP client. I tried different message lengths from the client but the delay was quite consistent.

API cy_socket_recv() should just read the buffer and I am wondering why it took that long.

I am working on an application which requires the device (uses the same PSoC6 MCU and the same Wi-Fi/BT chip) to use Wi-Fi communication and act as a TCP server. So I used the AnyCloud TCP Server example project as the basic code structure. The device needs to read something from the client and then take some action as quickly as possible. The long delay of calling cy_socket_recv() is not acceptable for my application.

Any idea how to get rid of the delay? Maybe there is another API which is better in terms of response time?

Thank you.

 

From AnyCloud TCP Server example project:

static cy_rslt_t tcp_receive_msg_handler(cy_socket_t socket_handle, void *arg)
{
char message_buffer[MAX_TCP_RECV_BUFFER_SIZE];
cy_rslt_t result;

/* Variable to store number of bytes received from TCP client. */
uint32_t bytes_received = 0;


cyhal_gpio_toggle(CYBSP_USER_LED);

result = cy_socket_recv(socket_handle, message_buffer, MAX_TCP_RECV_BUFFER_SIZE,
CY_SOCKET_FLAGS_NONE, &bytes_received);  // Long delay when calling this

cyhal_gpio_toggle(CYBSP_USER_LED);


if(result == CY_RSLT_SUCCESS)
{
/* Terminate the received string with '\0'. */
message_buffer[bytes_received] = '\0';
printf("\r\nAcknowledgement from TCP Client: %s\n", message_buffer);

/* Set the LED state based on the acknowledgement received from the TCP client. */
if(strcmp(message_buffer, "LED ON ACK") == 0)
{
led_state = CYBSP_LED_STATE_ON;
}
else
{
led_state = CYBSP_LED_STATE_OFF;
}
}
else
{
printf("Failed to receive acknowledgement from the TCP client. Error: 0x%08"PRIx32"\n",
(uint32_t)result);
if(result == CY_RSLT_MODULE_SECURE_SOCKETS_CLOSED)
{
/* Disconnect the socket. */
cy_socket_disconnect(socket_handle, 0);
}
}

printf("===============================================================\n");
printf("Press the user button to send LED ON/OFF command to the TCP client\n");

return result;
}

0 Likes
1 Solution

I have a possible workaround for this.

The issue is caused because, when the cy_socket_recv() is called and  if you keep digging further into the network level API's called by this, you will ultimately arrive at the point 

ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks); at line 402 of libs\wifi-mw-core\lwip-whd-port\arch\sys_arch.c
After receiving the number of bytes being sent, since the API 
network_receive() in file libs\secure-sockets\source\COMPONENT_LWIP\cy_secure_sockets.c expects additional bytes, this keeps running and once the timeout occurs in the xQueueReceive() as specified above, the code proceeds further.
Now since we don't have an implementation for 
CY_SOCKET_FLAGS_MORE to be passed as a parameter to cy_socket_recv() as of now, what you can do is assign a value for the timeout as needed.
I added the following line at libs\secure-sockets\source\COMPONENT_LWIP\cy_secure_sockets.c after  ctx = (cy_socket_ctx_t *)handle; in the API  cy_socket_recv()
ctx->conn_handler->recv_timeout = 1000;
Now this recv_timeout is set to a value of 10000 by default and changing it to 1000 reduced it by a factor of 10. You can change it to whatever the value that is needed.
 
Hope this helps.
 
Also, in my previous response I had thought that SYS_ARCH_TIMEOUT may help this out, but this isn't the case and need not be changed.
Let me know if anything else is needed.
 
Thanks

 

View solution in original post

0 Likes
7 Replies
Murali_R
Moderator
Moderator
Moderator
250 sign-ins 250 replies posted 100 solutions authored

@JoCh_1493306 

Is the MAX_TCP_RECV_BUFFER_SIZE in the cy_socket_recv()  greater than the number of bytes that you are sending. If so, this delay is expected. The cy_socket_recv() waits for the number of bytes as specified by MAX_TCP_RECV_BUFFER_SIZE. If doesn't happen in the stipulated time, then it times out and moves ahead and hence the delay.

Thanks 

0 Likes

Hi,

Thank you for this info. I tried and reduced the MAX_TCP_RECV_BUFFER_SIZE. The delay was much shorter if the message sent from the client has length >= MAX_TCP_RECV_BUFFER_SIZE (if the message size is larger than the buffer size, the message received is not correct obviously). However, if the message length is smaller than the buffer size, I would still see the delay.

In my application I would have different message lengths, varying from 10 to 100 bytes (what length of the message would be coming is random so no way to predict and set the buffer size before the message arrives). If I set the buffer size to be 100, it would still be very slow when the message length is 10 bytes.

Is there a way to reduce the timeout setting for this API? Or is there other solution for this problem?

Thanks.

0 Likes

I have a suggestion on how this could be worked around from the sender side.

You could append the data from the sender side to the length that you have set in MAX_TCP_RECV_BUFFER_SIZE and do some processing on the client side to remove this appended data out.

If you want to reduce the timeout on the receiver side that is on the board, can you try reducing the 

SYS_ARCH_TIMEOUT at libs\lwip\src\include\lwip\sys.h and see if this helps out?
 
0 Likes

Hi Murali,

I could only locate the sys.h in this directory: C:\Users\xxx\WorkspaceFolder\mtb_shared\lwip\STABLE-2_1_2_RELEASE\src\include\lwip\sys.h

The original value of SYS_ARCH_TIMEOUT is 0xffffffffUL. what is the unit of that? Is it in micro second? I tried to reduced it to 0xffffUL but the delay looks the same to me. Then I tried to reduce it to 0x1UL, and the code got stuck when it receives some message from the client (not sure if SYS_ARCH_TIMEOUT is used by something else that if it's set too short it would crash the code?). Can you provide more instructions on what proper value I should change it to?

I have no control on the TCP client who sends out the message. The message length varies between 10 to 100 bytes and I can't force it to always send the message with the same length.

Thanks!

0 Likes

Hi Murali,

Do you have any update on this or we get into a roadblock on this? Thanks!

0 Likes

I have a possible workaround for this.

The issue is caused because, when the cy_socket_recv() is called and  if you keep digging further into the network level API's called by this, you will ultimately arrive at the point 

ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks); at line 402 of libs\wifi-mw-core\lwip-whd-port\arch\sys_arch.c
After receiving the number of bytes being sent, since the API 
network_receive() in file libs\secure-sockets\source\COMPONENT_LWIP\cy_secure_sockets.c expects additional bytes, this keeps running and once the timeout occurs in the xQueueReceive() as specified above, the code proceeds further.
Now since we don't have an implementation for 
CY_SOCKET_FLAGS_MORE to be passed as a parameter to cy_socket_recv() as of now, what you can do is assign a value for the timeout as needed.
I added the following line at libs\secure-sockets\source\COMPONENT_LWIP\cy_secure_sockets.c after  ctx = (cy_socket_ctx_t *)handle; in the API  cy_socket_recv()
ctx->conn_handler->recv_timeout = 1000;
Now this recv_timeout is set to a value of 10000 by default and changing it to 1000 reduced it by a factor of 10. You can change it to whatever the value that is needed.
 
Hope this helps.
 
Also, in my previous response I had thought that SYS_ARCH_TIMEOUT may help this out, but this isn't the case and need not be changed.
Let me know if anything else is needed.
 
Thanks

 
0 Likes

I reduced ctx->conn_handler->recv_timeout to 10 and the response time is much shorter! It works great, thank you!

0 Likes