cancel
Showing results for 
Search instead for 
Did you mean: 

How to transmit non-echo TCP packets using Netx?

AMend.5
Associate III

Hi

I must have done something wrong in the function below to transmit a buffer on a tcp socket. If transmitting up to 4096 bytes the function works fine. If len is greater than that, nx_tcp_socket_send fails. How to stream a buffer correctly using Netx?

void TCP_Send(void *buf, uint32_t len)

{

 UINT ret;

 NX_PACKET *send_packet;

nx_packet_allocate(&AppPool,&send_packet,NX_TCP_PACKET,NX_WAIT_FOREVER);  

nx_packet_data_append(send_packet,buf,len,&AppPool,NX_WAIT_FOREVER);

ret = nx_tcp_socket_send(&TCPSocket, send_packet, NX_WAIT_FOREVER);

if(ret) nx_packet_release(send_packet);

}  

1 ACCEPTED SOLUTION

Accepted Solutions

Hello @Community member​ ,

As specified by MS documentation: application data larger than the payload size would require multiple packets chained together. When filling a packet with user data, the application shall use the service nx_packet_data_append.

And it is clearly said: In situations where a packet is not enough to hold user data, additional packets are allocated to store user data.

So before calling nx_packet_data_append, we must have the needed packets number.

After that the nx_tcp_socket_send() is called and also this function will do additional packets allocation in order to do fragmentation..

So before calling nx_packet_data_append, we must have the needed packets number.

Lets explain that with example using Nx_TCP_Echo_Server application and without changing any Pool’s parameters.

- Example 1: transmit 4000 bytes:

//Before calling nx_packet_data_append, AppPool->nx_packet_pool_available = 4

ret = nx_packet_data_append(send_packet,buf,len,&AppPool,NX_WAIT_FOREVER);

//len = 4000 and the number of available bytes in the packet is 1480 so we need allocate 2 more packets in fact 1480 + 1480*2 = 4440 > 4000

//So after calling nx_packet_data_append AppPool->nx_packet_pool_available = 2

ret = nx_tcp_socket_send(&TCPSocket, send_packet, NX_WAIT_FOREVER); // -> OK

//len = 4000 and tcp_window = 1460 so to do fragmentation we need to allocate 2 more packets in fact 1460 + 1460*2 = 4380 > 4000

//So after calling nx_tcp_socket_send AppPool->nx_packet_pool_available = 0

 

- Example 2: transmit 7000 bytes:

//Before calling nx_packet_data_append AppPool->nx_packet_pool_available = 4

ret = nx_packet_data_append(send_packet,buf,len,&AppPool,NX_WAIT_FOREVER);

//len = 7000 and the number of available bytes in the packet is 1480 so we need to allocate 4 more packets in fact 1480 + 1480*4 = 7400 > 7000

//So after calling nx_packet_data_append AppPool->nx_packet_pool_available = 0 -> so we can not call nx_tcp_socket_send and do fragmentation.

ret = nx_tcp_socket_send (&TCPSocket, send_packet, NX_WAIT_FOREVER); // -> KO

Just to make it short, the maximum payload is a multiple of tcp_window. So, you can adjust your allocation to fit any size, and the transmission will be done automatically once the required data size is reached. tcp_window should be 1480 in most examples. Therefore, the maximum number of bytes to be transmitted can be deduced as explained above.

Hope this Helps.

Walid

View solution in original post

9 REPLIES 9

Hello @Community member​ ,

Your problem has been reported internally. I will keep you updated.

Thank you for your understanding.

BeST Regards,

Walid

Hello @Community member​,

We have increased the buffer size to more 4096, but we don't see any problems.

Could you please share your example to reproduce your issue?

Thanks in advance.

Walid

AMend.5
Associate III

Walid,

I reproduced the problem on a NUCLEO-H723ZG board, so it's easier for you to test.

just replace the file "app_netxduo.c" in the path: ...\Repository\Packs\STMicroelectronics\X-CUBE-AZRTOS-H7\1.0.0\Projects\NUCLEO-H723ZG\Applications\NetXDuo\Nx_TCP_Echo_Server\NetXDuo\App by the Attached file.

It can also be tested with the same result if using the NUCLEO-H743ZI board, just lower the CPU clock to 400MHZ.

How to test:

Connect using an fixed IP, and Port valeu 6000.

If you send the character 'c', a buffer with 6144 bytes is filled with 1536 values of a sine function.

If you send the 'a' character, only 4096 bytes of this buffer are sent. In this case the transmission is successful.

If you send the 'b' character, all 6144 bytes are sent, in which case the transmission fails.

I tried to change the number 10 in the macro below to a higher value (24), but in this case the application doesn't even connect.

#define NX_PACKET_POOL_SIZE   (( PAYLOAD_SIZE + sizeof(NX_PACKET)) * 10)

I don't believe my Windows TCP client application is the problem. Because I tested it by communicating with an equivalent application made with LwIP.

Hello @Community member​ ,

We have good news for you ��

Issue reproduced on our side. It’s an allocation issue due to lack of pool size.

Just you need to update the following settings to avoid it:

  • In app_netxduo.h :

#define NX_PACKET_POOL_SIZE     (( PAYLOAD_SIZE + sizeof(NX_PACKET)) * 20)

  • In app_azure_rtos_config.h :

#define NX_APP_MEM_POOL_SIZE                    40*1024

  • In main.c :

#pragma location=0x24044000

ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */

#pragma location=0x24044060

ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */

MPU_InitStruct.BaseAddress = 0x24044000;

  • In stm32h723xx_flash_rw_sram1.icf

define symbol __ICFEDIT_region_NXDATA_start__ = 0x24044200;

Please let me know if this solves your problem.

BeST Regards,

Walid

AMend.5
Associate III

Walid,

Improved but the problem is still not resolved. Some packets with 6144 bytes are transmitted successfully, others are not.

Anyway, this solution of increasing the memory allocation doesn't seem to be the right solution, since I can't keep increasing the memory allocation indefinitely if I want to transmit larger amounts of bytes. How would I modify my function "TCP_Send(void *buf, uint32_t len)" to check if the amount of bytes being transmitted is too large and transmit in chunks?

Could please indicate the packet transmission frequency ?

AMend.5
Associate III

Walid,

My TCP client application running on PC requests a packet when I click a button. So it is not a throughput

issue.

How to modify my the TCP_Send(void *buf, uint32_t len) function to transmit any number of bytes, without having to allocate more memory?

Hello @Community member​ ,

As specified by MS documentation: application data larger than the payload size would require multiple packets chained together. When filling a packet with user data, the application shall use the service nx_packet_data_append.

And it is clearly said: In situations where a packet is not enough to hold user data, additional packets are allocated to store user data.

So before calling nx_packet_data_append, we must have the needed packets number.

After that the nx_tcp_socket_send() is called and also this function will do additional packets allocation in order to do fragmentation..

So before calling nx_packet_data_append, we must have the needed packets number.

Lets explain that with example using Nx_TCP_Echo_Server application and without changing any Pool’s parameters.

- Example 1: transmit 4000 bytes:

//Before calling nx_packet_data_append, AppPool->nx_packet_pool_available = 4

ret = nx_packet_data_append(send_packet,buf,len,&AppPool,NX_WAIT_FOREVER);

//len = 4000 and the number of available bytes in the packet is 1480 so we need allocate 2 more packets in fact 1480 + 1480*2 = 4440 > 4000

//So after calling nx_packet_data_append AppPool->nx_packet_pool_available = 2

ret = nx_tcp_socket_send(&TCPSocket, send_packet, NX_WAIT_FOREVER); // -> OK

//len = 4000 and tcp_window = 1460 so to do fragmentation we need to allocate 2 more packets in fact 1460 + 1460*2 = 4380 > 4000

//So after calling nx_tcp_socket_send AppPool->nx_packet_pool_available = 0

 

- Example 2: transmit 7000 bytes:

//Before calling nx_packet_data_append AppPool->nx_packet_pool_available = 4

ret = nx_packet_data_append(send_packet,buf,len,&AppPool,NX_WAIT_FOREVER);

//len = 7000 and the number of available bytes in the packet is 1480 so we need to allocate 4 more packets in fact 1480 + 1480*4 = 7400 > 7000

//So after calling nx_packet_data_append AppPool->nx_packet_pool_available = 0 -> so we can not call nx_tcp_socket_send and do fragmentation.

ret = nx_tcp_socket_send (&TCPSocket, send_packet, NX_WAIT_FOREVER); // -> KO

Just to make it short, the maximum payload is a multiple of tcp_window. So, you can adjust your allocation to fit any size, and the transmission will be done automatically once the required data size is reached. tcp_window should be 1480 in most examples. Therefore, the maximum number of bytes to be transmitted can be deduced as explained above.

Hope this Helps.

Walid

AMend.5
Associate III

Walid, thanks for the detailed explanation.