[STM32H7] Chapter 8 TCP server of ThreadX NetXDUO

Posted by jwadenpfuhl on Fri, 07 Jan 2022 10:56:46 +0100

Latest tutorial Download: http://www.armbbs.cn/forum.php?mod=viewthread&tid=104619

Chapter 8: TCP server of ThreadX NetXDUO

This chapter explains the TCP server implementation of NetXDUO. Before learning this chapter, you must give priority to learning the basic knowledge of TCP transmission control protocol in Chapter 7. With these basic knowledge, this chapter will have twice the effect with half the effort.

8.1 important tips for beginners

8.2 TCP server API functions

8.3 implementation method of TCP server

8.4 commissioning operation steps of network commissioning assistant and board

8.5 experimental routine description

8.6 summary

 

 

8.1 important tips for beginners

1. Before learning this chapter, make sure you have learned the basic knowledge of Chapter 7.

2. There are a few functions to master in this chapter. You can learn the basic use first, and then deeply understand the precautions in the use of these functions, so as to achieve proficient use.

3. Relationship between socket and listening:

  • Only one listener can be created for a socket created.
  • One socket created cannot listen to multiple.
  • You can create multiple listeners by creating multiple socket s.
  • Creating multiple socket s can create only one listener.

8.2} TCP server API functions

The following figure illustrates various API playing methods of ThreadX NetXDUO TCP Socket:

 

8.2.1} function nx_system_initialize

Function prototype:

VOID nx_system_initialize(VOID); 

Function Description:

NetXDUO initialization, this function must be called before all other function calls.

8.2.2} function nx_packet_pool_create

Function prototype:

UINT nx_packet_pool_create(
                          NX_PACKET_POOL *pool_ptr,
                          CHAR *name,
                          ULONG payload_size,
                          VOID *memory_ptr,
                          ULONG memory_size);                 

Function Description:

This function is used for packet memory pool creation

Function parameters:

  1. The first parameter is the address of the memory pool control block.
  2. The second parameter is the memory pool name.
  3. The third parameter is the number of bytes per packet in the memory pool. This value must be at least 40 bytes and must be divisible by 4.
  4. The fourth parameter is the data address in the memory pool, which must be aligned with ULONG.
  5. The fifth parameter is the memory pool size.
  6. Return value:
  •   NX_SUCCESS: (0x00) successfully created memory pool.
  •   NX_PTR_ERROR: (0x07) the first parameter address is invalid.
  •   NX_SIZE_ERROR: (0x09) the fifth parameter memory pool size is invalid.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.

Use examples:

  /* Create memory pool */
    status =  nx_packet_pool_create(&pool_0,                 /* Memory pool control block */
                                    "NetX Main Packet Pool",/* Memory pool name */
               1536, /* The size of each packet in the memory pool, in bytes. This value must be at least 40 bytes and must be divisible by 4 */
             (ULONG*)(((int)packet_pool_area + 15) & ~15) ,/* Memory pool address, which must be aligned with ULONG */
               NX_PACKET_POOL_SIZE);                        /* Memory pool size */       

8.2.3} function nx_ip_create

Function prototype:

UINT nx_ip_create(
    NX_IP *ip_ptr, 
    CHAR *name, ULONG ip_address,
    ULONG network_mask, 
    NX_PACKET_POOL *default_pool,
    VOID (*ip_network_driver)(NX_IP_DRIVER *),
    VOID *memory_ptr, 
    ULONG memory_size,
    UINT priority);                    

Function Description:

This function creates an IP instance using the IP address, packet memory pool and network driver provided by the user. Note that the network driver will not be called until the IP task is executed.

Function parameters:

  1. The first parameter is the control block pointer to create the IP instance.
  2. The second parameter is the name of the IP instance.
  3. The third parameter is the IP address.
  4. The fourth parameter is the subnet mask
  5. The fifth parameter is the memory pool address.
  6. The sixth parameter is the network card driver address.
  7. The seventh parameter is the IP task stack address
  8. The eighth parameter is the IP task stack size, in bytes.
  9. The ninth parameter is IP task priority.
  10. Return value
  •   NX_SUCCESS: (0x00) IP instance created successfully.
  •   NX_NOT_IMPLEMENTED: (0x4A) NetX Duo library is not configured correctly.
  •   NX_PTR_ERROR: (0x07) invalid IP control block address, network driver function pointer, memory pool address or task stack address.
  •   NX_SIZE_ERROR: (0x09) the provided task stack size is too small.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_IP_ADDRESS_ERROR: (0x21) the IP address provided is invalid.
  •   NX_OPTION_ERROR: (0x21) the IP task priority provided is invalid.

Use examples:

/* Instantiated IP */
    status = nx_ip_create(&ip_0,                                                   /* IP Instance control block */                                    
                            "NetX IP Instance 0",                                  /* IP Instance name */     
                            IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3),    /* IP address */
                            0xFFFFFF00UL,                                          /* Subnet mask */
                            &pool_0,                                               /* Memory pool */
                        nx_driver_stm32h7xx,                                   /* Network card driver */
                            (UCHAR*)AppTaskNetXStk,                                /* IP Task stack address */
                            sizeof(AppTaskNetXStk),                             /* IP Task stack size, in bytes */
                            APP_CFG_TASK_NETX_PRIO);                            /* IP Task priority */

8.2.4} function nx_arp_enable

Function prototype:

UINT nx_arp_enable(
    NX_IP *ip_ptr, 
    VOID *arp_cache_memory,
    ULONG arp_cache_size);                

Function Description:

This function enables ARP address resolution.

Function parameters:

  1.   ip_ptr: IP instance address.
  2.   arp_cache_memory: ARP cache address.
  3.   arp_cache_size: each ARP entry is 52 bytes, so the total number of ARP entries is an integer multiple of 52 bytes.
  4. Return value
  •   NX_SUCCESS: (0x00) ARP enabled successfully.
  •   NX_PTR_ERROR: (0x07) invalid IP instance address or ARP cache address.
  •   NX_SIZE_ERROR: (0x09) the ARP cache memory provided by the user is too small.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_ALREADY_ENABLED: (0x15) this component is enabled.

Use examples:

int32_t tcp_sock;

tcp_sock = netTCP_GetSocket (tcp_cb_server);
    
if (tcp_sock > 0) 
{
res = netTCP_Listen (tcp_sock, PORT_NUM);
}

if(netTCP_SendReady(tcp_sock) == true )
{

}

8.2.5} function nx_ip_fragment_enable

Function prototype:

UINT nx_ip_fragment_enable(NX_IP *ip_ptr);

Function Description:

This function enables IPv4 and IPv6 packet segmentation and reorganization. This service is automatically disabled when an IP task is created.

Function parameters:

  1. The first parameter is the IP instance address.
  2. Return value
  •   NX_SUCCESS: (0x00) IP segmentation enabled successfully.
  •   NX_PTR_ERROR: (0x07) invalid IP instance address.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) IP segmentation function is not compiled into NetX Duo.

Use examples:

    /* Enable fragment */    
    status = nx_ip_fragment_enable(&ip_0);

8.2.6} function nx_tcp_enable

Function prototype:

UINT nx_tcp_enable(NX_IP *ip_ptr);  

Function Description:

This function enables the TCP component.

Function parameters:

  1. The first parameter is the IP instance address.
  2. Return value
  •   NX_SUCCESS: (0x00) TCP enabled successfully.
  •   NX_ALREADY_ENABLED: (0x15) TCP enabled.
  •   NX_PTR_ERROR: (0x07) invalid IP instance address.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.

Use examples:

    /* Enable TCP */
    status =  nx_tcp_enable(&ip_0);

8.2.7} function nx_tcp_socket_create

Function prototype:

UINT nx_tcp_socket_create(
    NX_IP *ip_ptr, 
    NX_TCP_SOCKET *socket_ptr,
    CHAR *name, 
    ULONG type_of_service, 
    ULONG fragment,
    UINT time_to_live, 
    ULONG window_size,
    VOID (*urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
    VOID (*disconnect_callback)(NX_TCP_SOCKET *socket_ptr));

Function Description:

This function is used to create a TCP Socket.

Function parameters:

1. The first parameter is the IP instance address.

2. The second parameter is the TCP control block address.

3. The third parameter is the name of the task control block.

4. The fourth parameter is the service type. The supported parameters are as follows:

  •   NX_IP_NORMAL (0x00000000)
  •   NX_IP_MIN_DELAY (0x00100000)
  •   NX_IP_MAX_DATA (0x00080000)
  •   NX_IP_MAX_RELIABLE (0x00040000)
  •   NX_IP_MIN_COST (0x00020000)

5. The fifth parameter specifies whether IP segmentation is allowed. If NX is specified_ FRAGMENT_ Okay (0x0), IP segmentation is allowed. If NX is specified_ DONT_ Fragment (0x4000), IP segmentation is prohibited.

6. The sixth parameter specifies an 8-bit value to define the number of routers that this packet can pass through before being discarded. The default value is determined by NX_IP_TIME_TO_LIVE specifies.

7. The seventh parameter defines the maximum number of bytes allowed in the TCP Socket receive queue.

8. The eighth parameter is used to call the callback function when emergency data is detected in the receiving stream. If this value is NX_NULL, the emergency data is ignored.

9. The ninth parameter is the callback function called when the other end of the TCP Socket sends a disconnection. If this value is NX_NULL, the disconnect callback function is disabled.

10. Return value:

  •   NX_SUCCESS: (0x00) TCP Socket created successfully.
  •   NX_OPTION_ERROR: (0x0A) invalid service type, segment, window size or lifetime options.
  •   NX_PTR_ERROR: (0x07) invalid IP instance or TCP Socket pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

matters needing attention:

  1. The application callback (the 9th parameter) is called in the IP task.

Use examples:

/* Create TCP Socket */
    ret = nx_tcp_socket_create(&ip_0,                 /* IP Instance control block */    
                               &TCPSocket,            /* TCP Control block */ 
                               "TCP Server Socket",   /* TCP Socket name */ 
                               NX_IP_NORMAL,          /* IP Service type */ 
                               NX_FRAGMENT_OKAY,      /* Enable IP segmentation */ 
                               NX_IP_TIME_TO_LIVE,    /*Used to define the number of routers that this packet can pass through before being discarded */ 
                               4320,                  /* TCP Socket The maximum number of bytes allowed in the receive queue */ 
                               NX_NULL,               /* Callback function called when emergency data is detected in the receive stream */
                               NX_NULL);              /* TCP Socket The other end issues a callback function called when the connection is disconnected */

8.2.8} function nx_tcp_server_socket_listen

Function prototype:

UINT nx_tcp_server_socket_listen(
     NX_IP *ip_ptr, UINT port,
     NX_TCP_SOCKET *socket_ptr,
     UINT listen_queue_size,
     VOID (*listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT port));

Function Description:

This function listens for client connection requests on the specified TCP port. When receiving a client connection request, the provided server Socket will be bound to the specified port and call the provided listening callback function.

If the application wants to handle other client connections on the same port, it must call NX with the available Socket (the Socket in the closed state)_ tcp_ server_ Socket_ RELISTEN to establish the next connection. Other client connections are queued before re listening is called. When the maximum queue depth is exceeded, the oldest connection request is discarded and the new connection request is queued. The maximum queue depth is specified by this function.

Function parameters:

  1. The first parameter is the IP instance address.
  2. The second parameter is the port number to listen on, ranging from 0 – 0xFFFF.
  3. The third parameter is the Socket address.
  4. The fourth parameter is the number of connections that can be monitored.
  5. The fifth parameter is the listening callback function. If it is set to NULL, the listening callback will not be used.
  6. Return value
  •   NX_SUCCESS: (0x00) enable TCP port listening successfully.
  •   NX_MAX_LISTEN: (0x33) no more listening requests available, nx_ api. Constant NX defined in H_ MAX_ LISTEN_ Requests defines the maximum number of listening requests.
  •   NX_NOT_CLOSED: (0x35) the Socket provided is not closed.
  •   NX_ALREADY_BOUND: (0x22) the Socket provided has been bound to a port.
  •   NX_DUPLICATE_LISTEN: (0x34) Socket request already exists on this port.
  •   NX_INVALID_PORT: (0x46) invalid port specified.
  •   NX_PTR_ERROR: (0x07) invalid IP instance address or Socket address.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

matters needing attention:

  1. The listening callback is called in the IP task.

Use examples:

/*
    * Listen for new links.
    * Create callback TCP_listen_callback indicates that a new connection is being listened to.
    */
    ret = nx_tcp_server_socket_listen(&ip_0,                  /* IP Instance control block */  
                                  DEFAULT_PORT,           /* Default port */          
                                      &TCPSocket,             /* TCP Socket Control block */
                                      MAX_TCP_CLIENTS,        /* Number of connections that can be monitored */
                                      NULL);                  /* Listening callback function */

8.2.9} function nx_tcp_server_socket_relisten

Function prototype:

UINT nx_tcp_server_socket_relisten(
    NX_IP *ip_ptr, 
    UINT port,
    NX_TCP_SOCKET *socket_ptr);

Function Description:

After receiving the connection on the previously monitored port, you can call the function. The main purpose of this function is to provide a new Socket for the next client connection. If there are already queued connection requests, the connection is processed immediately during the call to this function.

Function parameters:

  1. The first parameter is the IP instance address.
  2. The second parameter is the listening port number, ranging from 0 – 0xFFFF.
  3. The third parameter is the Socket used for the next client connection.
  4. Return value: return the following status values:
  •   NX_SUCCESS: (0x00) re listening TCP port succeeded.
  •   NX_NOT_CLOSED: (0x35) the Socket provided is not closed.
  •   NX_ALREADY_BOUND: (0x22) the Socket provided has been bound to a port.
  •   NX_ INVALID_ Listen: (0x47) this port already has a valid Socket or the specified port to listen for requests.
  •   NX_CONNECTION_PENDING: (0x48) and NX_SUCCESS is the same, except that there is a queued connection request and the request has been processed during the call.
  •   NX_INVALID_PORT: (0x46) invalid port specified.
  •   NX_PTR_ERROR: (0x07) invalid IP instance address or listening callback.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

matters needing attention:

  1. Function nx_ tcp_ server_ socket_ This function will also be called for the listening callback set by listen.

Use examples:

  /* Re listening */
   nx_tcp_server_socket_relisten(&ip_0, 
                              DEFAULT_PORT, 
                             &TCPSocket);

8.2.10} function nx_tcp_server_socket_accept

Function prototype:

UINT nx_tcp_server_socket_accept(
         NX_TCP_SOCKET *socket_ptr,
         ULONG wait_option);    

Function Description:

This function is used to receive TCP client connection requests. This function can be called immediately after the user calls the listening or re listening function, or after listening to the callback function. When the connection cannot be established immediately, this function will hang according to the waiting parameters.

Function parameters:

1. The first parameter is the TCP Socket control block address.

2. The second parameter is the wait option. The supported parameters are as follows:

  •   NX_NO_WAIT (0x00000000).
  •   NX_WAIT_FOREVER (0xFFFFFFFF).
  • Timeout value in clock cycles (0x00000001 to 0xFFFFFFFE).

3. Return value: return the following status values:

  •   NX_SUCCESS: (0x00) successful acceptance of TCP Socket (passive connection).
  •   NX_NOT_LISTEN_STATE: (0x36) the provided TCP Socket is not in listening state.
  •   NX_IN_PROGRESS: (0x37) wait is not specified, connection attempt is in progress.
  •   NX_WAIT_ABORTED: (0x1A) passed the call tx_thread_wait_abort abort pending.
  •   NX_PTR_ERROR: (0x07)Socket pointer error.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

matters needing attention:

  1. After the connection is no longer needed, the application must call nx_tcp_server_socket_unaccept to delete the binding between the Socket and the server port.
  2. The application callbacks are invoked in the IP task.

Use examples:

/* Receive new connections before starting TCP communication */
ret = nx_tcp_server_socket_accept(&TCPSocket,       /* TCP Socket Control block */
                               TX_WAIT_FOREVER); /* Waiting for connection */

if (ret)
{
    Error_Handler(__FILE__, __LINE__);
}

8.2.11} function nx_tcp_server_socket_unaccept

Function prototype:

UINT nx_tcp_server_socket_unaccept(NX_TCP_SOCKET *socket_ptr);

Function Description:

This service is used to delete the binding between Socket and server port. The application must call this function after the connection is disconnected or when no connection is successfully received.

Function parameters:

  1. The first parameter is the TCP Socket pointer.
  2. Return value: return the following status values:
  •   NX_SUCCESS: (0x00) successfully unaccepted server socket.
  •   NX_NOT_LISTEN_STATE: (0x36) the server socket is in an incorrect state and may not be disconnected.
  •   NX_PTR_ERROR: (0x07) invalid socket pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

Use examples:

/* Unbind Socket and server port */
nx_tcp_server_socket_unaccept(&TCPSocket);

8.2.12} function nx_tcp_socket_info_get

Function prototype:

UINT nx_tcp_socket_info_get(
    NX_TCP_SOCKET *socket_ptr,
    ULONG *tcp_packets_sent,
    ULONG *tcp_bytes_sent,
    ULONG *tcp_packets_received,
    ULONG *tcp_bytes_received,
    ULONG *tcp_retransmit_packets,
    ULONG *tcp_packets_queued,
    ULONG *tcp_checksum_errors,
    ULONG *tcp_socket_state,
    ULONG *tcp_transmit_queue_depth,
    ULONG *tcp_transmit_window,
    ULONG *tcp_receive_window);

Function Description:

Used to obtain TCP Socket related information.

Function parameters:

  1. The first parameter is the TCP Socket pointer.
  2. The second parameter is the total number of TCP packets sent.
  3. The third parameter is the total number of TCP bytes sent.
  4. The fourth parameter is the total number of TCP packets received.
  5. The fifth parameter is the total number of TCP bytes received.
  6. The sixth parameter is the total number of TCP packets retransmitted.
  7. The seventh parameter is the total number of TCP packets queued by TCP on the Socket.
  8. The eighth parameter is the total number of TCP packets with checksum errors on the Socket.
  9. The ninth parameter is the current status of the Socket.
  10. The 10th parameter is the total number of sent packets still queued for ACK.
  11. The 11th parameter is the current sending window size.
  12. The 12th parameter is the current receive window size.
  13. Return value:
  •   NX_SUCCESS: (0x00) successfully retrieved TCP Socket information.
  •   NX_PTR_ERROR: (0x07) invalid Socket pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

Use examples:

   /* Get socket status */
        nx_tcp_socket_info_get(&TCPSocket,     /* TCP Socket Control block */
                               NULL,           /* Total number of TCP packets sent */
                               NULL,           /* Total TCP bytes sent */
                               NULL,           /* Total number of TCP packets received */
                               NULL,           /* Total TCP bytes received */
                               NULL,           /* The total number of TCP packets retransmitted */
                               NULL,           /* Socket The total number of TCP packets queued on TCP */
                               NULL,           /* Socket The total number of TCP packets with checksum errors on */
                               &socket_state,  /* Socket current state */
                               NULL,           /* The total number of sent packets still queued for ACK */
                               NULL,           /* Current send window size */
                               NULL);          /* Current receive window size */

8.2.13} function nx_tcp_socket_receive

Function prototype:

UINT nx_tcp_socket_receive(
    NX_TCP_SOCKET *socket_ptr,
    NX_PACKET **packet_ptr,
    ULONG wait_option);

Function Description:

This function is used to receive TCP data from the specified Socket. If there is no queued data on the specified Socket, the caller will suspend according to the provided wait option parameters.

Function parameters:

1. The first parameter is the TCP Socket pointer

2. The second parameter is the TCP packet pointer.

3. The third parameter is the processing when there is no data on the Socket queue:

  •   NX_NO_WAIT (0x00000000).
  •   NX_WAIT_FOREVER (0xFFFFFFFF).
  • Timeout value in clock cycles (0x00000001 to 0xFFFFFFFE).

4. Return value:

  •   NX_SUCCESS: (0x00) Socket data received successfully.
  •   NX_NOT_BOUND: (0x24) Socket is not bound.
  •   NX_NO_PACKET: (0x01) no data received.
  •   NX_WAIT_ABORTED: (0x1A) by calling tx_thread_wait_abort abort pending.
  •   NX_NOT_CONNECTED: (0x38) the Socket is no longer connected.
  •   NX_PTR_ERROR: (0x07) invalid socket pointer or return packet pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

matters needing attention:

  1. If NX is returned_ Success, the application is responsible for releasing the packet when it is no longer necessary to receive it.

Use examples:

/* Receive TCP packets from TCP clients */
ret = nx_tcp_socket_receive(&TCPSocket,        /* TCP Socket Control block */
                          &data_packet,      /* Received packets */
                           NX_WAIT_FOREVER);  /* Permanent waiting */

8.2.14} function nx_tcp_socket_send

Function prototype:

UINT nx_tcp_socket_send(
    NX_TCP_SOCKET *socket_ptr,
    NX_PACKET *packet_ptr,
    ULONG wait_option);

Function Description:

This function is used to send TCP Socket data. If the last recommended window size of the receiver is lower than this request, this function can suspend according to the specified waiting parameters. This function ensures that packets larger than MSS will not be sent to the IP layer.

Function parameters:

1. The first parameter is the TCP Socket handle.

2. The second parameter is the TCP packet pointer.

3. The third parameter is the parameter processing when the sent packet is larger than the receiver's window size. The following parameters are supported:

  •   NX_NO_WAIT (0x00000000)
  •   NX_WAIT_FOREVER (0xFFFFFFFF)
  • Timeout value in clock cycles (0x00000001 to 0xFFFFFFFE)

4. Return value: return the following status values:

  •   NX_SUCCESS: (0x00) Socket sent successfully.
  •   NX_NOT_BOUND: (0x24) Socket is not bound to any port.
  •   NX_NO_INTERFACE_ADDRESS: (0x50) no suitable outgoing interface was found.
  •   NX_NOT_CONNECTED: (0x38) the socket is no longer connected.
  •   NX_WINDOW_OVERFLOW: (0x39) the request is larger than the window size advertised by the receiver (in bytes).
  •   NX_WAIT_ABORTED: (0x1A) passed the call tx_thread_wait_abort aborts the requested suspend.
  •   NX_INVALID_PACKET: (0x12) packet is not allocated.
  •   NX_TX_QUEUE_DEPTH: (0x49) the maximum transmission queue depth has been reached.
  •   NX_OVERFLOW: (0x03) invalid packet append pointer.
  •   NX_PTR_ERROR: (0x07) invalid socket pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.
  •   NX_UNDERFLOW: (0x02) invalid packet leading pointer.

matters needing attention:

  1. The application should not release the packet after calling this function unless an error is returned. This can lead to unpredictable results because the network driver will also try to release the packet after transmission.

Use examples:

/* Send the received data back immediately */
ret =  nx_tcp_socket_send(&TCPSocket,       /* TCP Socket Control block */
                        data_packet,      /* data packet */
                        NX_WAIT_FOREVER); /* Permanent waiting */

8.2.15} function nx_packet_data_retrieve

Function prototype:

UINT nx_packet_data_retrieve(
    NX_PACKET *packet_ptr,
    VOID *buffer_start,
    ULONG *bytes_copied);

Function Description:

This function copies the data in the supplied packet to the supplied buffer. The actual number of bytes copied is determined by the formal parameter bytes_ The storage unit pointed to by copied is returned.

Note that this function does not change the internal state of the packet. The retrieved data still exists in the packet.

Function parameters:

  1. The first parameter is a pointer to the source packet
  2. The second parameter is the address of the destination packet.
  3. The third parameter is the number of bytes to be copied and the storage address.
  4. Return value: return the following status values:
  •   NX_SUCCESS: (0x00) successfully copied packet data.
  •   NX_INVALID_PACKET: (0x12) invalid packet.
  •   NX_PTR_ERROR: (0x07) invalid parameter address.

matters needing attention:

The destination buffer must be large enough to hold the contents of the packet. Otherwise, the memory will be damaged, resulting in unpredictable results.

Use examples:

/* Get the data from the client */
 nx_packet_data_retrieve(data_packet,    /* Received packets */
                      data_buffer,    /* Parse out data */
                      &bytes_read);   /* data size */

8.2.16} function nx_packet_release

Function prototype:

UINT nx_packet_release(NX_PACKET *packet_ptr);

Function Description:

This function releases packets, including any other packets linked to the specified packet. If there are other tasks waiting for this packet, the task will get the packet and continue to execute.

Function parameters:

1. The first parameter is the packet address.

2. Return value: return the following status values:

  •   NX_SUCCESS: (0x00) packet release succeeded.
  •   NX_PTR_ERROR: (0x07) invalid packet pointer.
  •   NX_UNDERFLOW: (0x02) the preset pointer is less than the payload start position.
  •   NX_OVERFLOW: (0x03) the append pointer is greater than the payload end position.

matters needing attention:

The application must prevent releasing the same packet multiple times, otherwise it will lead to unpredictable results.

8.2.17} function nx_tcp_socket_disconnect

Function prototype:

UINT nx_tcp_socket_disconnect(
                 NX_TCP_SOCKET *socket_ptr,
                 ULONG wait_option);

Function Description:

This function is used to disconnect the established client or server Socket. After the server Socket is disconnected, there should be a cancel request, and the disconnected client Socket will be ready to accept other connection requests. If the disconnect process cannot be completed immediately, the function hangs according to the wait option provided.

Function parameters:

1. The first parameter is the TCP Socket address.

2. The second parameter supports the following parameters when waiting for disconnection:

  •   NX_NO_WAIT (0x00000000).
  •   NX_WAIT_FOREVER (0xFFFFFFFF).
  • Timeout value in clock cycles (0x00000001 to 0xFFFFFFFE).

3. Return value: return the following status values:

  •   NX_SUCCESS: (0x00) disconnect Socket successfully.
  •   NX_NOT_CONNECTED: (0x38) the specified Socket is not connected.
  •   NX_IN_PROGRESS: (0x37) disconnect in progress.
  •   NX_WAIT_ABORTED: (0x1A) passed the call tx_thread_wait_abort abort pending request.
  •   NX_PTR_ERROR: (0x07) invalid socket pointer.
  •   NX_CALLER_ERROR: (0x11) the caller of this service is invalid.
  •   NX_NOT_ENABLED: (0x14) this component is not enabled.

Use examples:

/* Disconnect */
nx_tcp_socket_disconnect(&TCPSocket, 
                        NX_WAIT_FOREVER);

8.3 implementation method of TCP server

8.3.1} NetXDUO initialization

Before creating a TCP server, initialize NetX, create a memory pool, and instantiate IP:

/*
*********************************************************************************************************
*    Function name: NetXTest
*    Function Description: TCPnet application
*    Formal parameters: None
*    Return value: None
*********************************************************************************************************
*/    
void NetXTest(void)
{
    UINT status;
    UINT ret;
    ULONG socket_state;
    UINT old_priority;

    NX_PACKET *data_packet;
    ULONG bytes_read;
    
    ULONG peer_ip_address;
    ULONG peer_port;
    
    
    /* Initialize NetX */
    nx_system_initialize();

    /* Create memory pool */
    status =  nx_packet_pool_create(&pool_0,                 /* Memory pool control block */
                                     "NetX Main Packet Pool",/* Memory pool name */
               1536, /* The size of each packet in the memory pool, in bytes. This value must be at least 40 bytes and must be divisible by 4 */
             (ULONG*)(((int)packet_pool_area + 15) & ~15) ,/* Memory pool address, which must be aligned with ULONG */
               NX_PACKET_POOL_SIZE);                        /* Memory pool size */                  
          
    /* Detect whether the creation failed */
    if (status) error_counter++;

    /* Instantiated IP */
    status = nx_ip_create(&ip_0,                                                   /* IP Instance control block */                                    
                            "NetX IP Instance 0",                                  /* IP Instance name */     
                            IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3),    /* IP address */
                            0xFFFFFF00UL,                                          /* Subnet mask */
                            &pool_0,                                               /* Memory pool */
                        nx_driver_stm32h7xx,                                   /* Network card driver */
                            (UCHAR*)AppTaskNetXStk,                                /* IP Task stack address */
                            sizeof(AppTaskNetXStk),                             /* IP Task stack size, in bytes */
                            APP_CFG_TASK_NETX_PRIO);                            /* IP Task priority */
                            
            
    /* Detect whether the creation failed */
    if (status) error_counter++;

    /* Enable ARP and provide ARP cache */
    status =  nx_arp_enable(&ip_0,               /* IP Instance control block */
                     (void *)arp_space_area,  /* ARP Cache address */
         sizeof(arp_space_area));   /* Each ARP entry is 52 bytes, so the total number of ARP entries is an integer multiple of 52 bytes */

    /* Enable fragment */    
    status = nx_ip_fragment_enable(&ip_0);

    /* Detection enable successful */
    if (status) error_counter++;

    /* Enable TCP */
    status =  nx_tcp_enable(&ip_0);

    /* Detection enable successful */
    if (status) error_counter++;

    /* Enable UDP  */
    status =  nx_udp_enable(&ip_0);

    /* Detection enable successful */
    if (status) error_counter++;

    /* Enable ICMP */
    status =  nx_icmp_enable(&ip_0);

    /* Detection enable successful */
    if (status) error_counter++;   
    
    /* NETX After initialization, reset the priority */
    tx_thread_priority_change(netx_thread_ptr, APP_CFG_TASK_NETX_PRIO1, &old_priority);
tx_thread_priority_change(&AppTaskNetXProTCB, APP_CFG_TASK_NetXPro_PRIO1, &old_priority);

    /* ellipsis */
}

At the end of the program, the service priority is specially treated. When creating, it is first set to low priority. After detecting the normal connection of the network cable and initializing the network, the priority is set to the normal level.

8.3.2} TCP server implementation

The following is how to create a TCP server and create a listener

/*
*********************************************************************************************************
*    Function name: NetXTest
*    Function Description: TCPnet application
*    Formal parameters: None
*    Return value: None
*********************************************************************************************************
*/    
void NetXTest(void)
{
  
     /* ellipsis */

    /* Create TCP Socket */
    ret = nx_tcp_socket_create(&ip_0,                 /* IP Instance control block */    
                               &TCPSocket,            /* TCP Control block */ 
                               "TCP Server Socket",   /* TCP Socket name */ 
                               NX_IP_NORMAL,          /* IP Service type */ 
                               NX_FRAGMENT_OKAY,      /* Enable IP segmentation */ 
                               NX_IP_TIME_TO_LIVE,    /*Used to define the number of routers that this packet can pass through before being discarded */ 
                               4320,                  /* TCP Socket The maximum number of bytes allowed in the receive queue */ 
                               NX_NULL,               /* Callback function called when emergency data is detected in the receive stream */
                               NX_NULL);              /* TCP Socket The other end issues a callback function called when the connection is disconnected */
    if (ret)
    {
        Error_Handler(__FILE__, __LINE__);    
    }

    /*
    * Listen for new links.
    * Create callback TCP_listen_callback indicates that a new connection is being listened to.
    */
    ret = nx_tcp_server_socket_listen(&ip_0,                  /* IP Instance control block */  
                                  DEFAULT_PORT,           /* Default port */          
                                      &TCPSocket,             /* TCP Socket Control block */
                                      MAX_TCP_CLIENTS,        /* Number of connections that can be monitored */
                                      NULL);                  /* Listening callback function */

    if (ret)
    {
        Error_Handler(__FILE__, __LINE__);
    }

    /* Receive new connections before starting TCP communication */
    ret = nx_tcp_server_socket_accept(&TCPSocket,         /* TCP Socket Control block */
                                       TX_WAIT_FOREVER);  /* Listening callback function */

    if (ret)
    {
        Error_Handler(__FILE__, __LINE__);
    }

     /* ellipsis */
}

8.3.3 implementation of TCP loopback communication

Loopback means that after the computer network assistant sends data to the board, the board returns the data.

/*
*********************************************************************************************************
*    Function name: NetXTest
*    Function Description: TCPnet application
*    Formal parameters: None
*    Return value: None
*********************************************************************************************************
*/    
void NetXTest(void)
{
  
     /* ellipsis */

    while(1)
    {
        TX_MEMSET(data_buffer, '\0', sizeof(data_buffer));

        /* Get socket status */
        nx_tcp_socket_info_get(&TCPSocket,     /* TCP Socket Control block */
                               NULL,           /* Total number of TCP packets sent */
                               NULL,           /* Total TCP bytes sent */
                               NULL,           /* Total number of TCP packets received */
                               NULL,           /* Total TCP bytes received */
                               NULL,           /* The total number of TCP packets retransmitted */
                               NULL,           /* Socket The total number of TCP packets queued on TCP */
                               NULL,           /* Socket The total number of TCP packets with checksum errors on */
                               &socket_state,  /* Socket current state */
                               NULL,           /* The total number of sent packets still queued for ACK */
                               NULL,           /* Current send window size */
                               NULL);          /* Current receive window size */

        /* If the connection has not been established, continue to accept the new connection. If successful, start receiving data */
        if(socket_state != NX_TCP_ESTABLISHED)
        {
            /* Receive new connections before starting TCP communication */
            ret = nx_tcp_server_socket_accept(&TCPSocket,       /* TCP Socket Control block */
                                              TX_WAIT_FOREVER); /* Waiting for connection */

            if (ret)
            {
                Error_Handler(__FILE__, __LINE__);
            }
        }
        
        if((socket_state == NX_TCP_ESTABLISHED)&&(ret == NX_SUCCESS))
        {
                
            /* Receive TCP packets from TCP clients */
            ret = nx_tcp_socket_receive(&TCPSocket,        /* TCP Socket Control block */
                                        &data_packet,      /* Received packets */
                                        NX_WAIT_FOREVER);  /* Permanent waiting */

            if (ret == NX_SUCCESS)
            {
                
                /* Get the IP address and port of the client */
                nx_tcp_socket_peer_info_get(&TCPSocket,       /* TCP Socket Control block */ 
                                            &peer_ip_address, /* Remote IP address */ 
                                            &peer_port);      /* Remote port number */

                /* Get the data from the client */
                nx_packet_data_retrieve(data_packet,    /* Received packets */
                                        data_buffer,    /* Parse out data */
                                        &bytes_read);   /* data size */

                /* Print received data */
                PRINT_DATA(peer_ip_address, (unsigned int)peer_port, data_buffer);

                /* Send the received data back immediately */
                ret =  nx_tcp_socket_send(&TCPSocket,       /* TCP Socket Control block */
                                          data_packet,      /* data packet */
                                          NX_WAIT_FOREVER); /* Permanent waiting */
            }
            else
            {
                /* Disconnect */
                nx_tcp_socket_disconnect(&TCPSocket, 
                                         NX_WAIT_FOREVER);
                
             /* Unbind Socket and server port */
                nx_tcp_server_socket_unaccept(&TCPSocket);
                
              /* Re listening */
                nx_tcp_server_socket_relisten(&ip_0, 
                                              DEFAULT_PORT, 
                                              &TCPSocket);
            }
        }
    }

     /* ellipsis */
}

8.4 commissioning operation steps of network commissioning assistant and board

We use the following debugging assistant here. Of course, any other network debugging assistant can be used without limitation:

 http://www.armbbs.cn/forum.php?mod=viewthread&tid=1568 .

8.4.1 test the DM916X network port used and pay attention to the jumper cap

During the test, the network cable shall be plugged into the DM916X network port:

Pay special attention to the position of jumper cap here and short circuit PG11:

8.4.2 green and yellow lights on RJ45 network transformer socket

Various network cards, switches and other network devices are different. Generally speaking, the green light is divided into on or off (representing the network speed), and the yellow light is divided into flashing or off (representing whether there is data transceiver).

Green light: long light means 100M; Not on means 10M.

Yellow light: long light means no data sending and receiving; Flashing indicates data transmission and reception.

The lights of some gigabit network cards are distinguished by color. If they are not on, it means 10M / green means 100M / yellow means 1000M. At present, the 10M network is basically invisible. If one light is on for a long time, it basically indicates that the 100m network is or higher, while the other light flashes from time to time, it means that there is data transceiver. The specific depends on the network equipment. Even some low-level network cards, such as TP-LINK, have only one light. When it is on, it represents connectivity, and flashing represents data sending and receiving.

For the light on the RJ45 network transformer socket on the development board, the green light represents data transmission and reception, the long light indicates no data transmission and reception, and the flashing represents data transmission and reception. The yellow light represents the network speed, the long light represents 100M, and the non light represents 10M.

8.4.3} step 1: set the board IP address

We use fixed IP (or static IP), which is easy to set. Here we will explain the direct connection between the development board and the computer, that is, directly connect the network port of the development board with the network port of the computer through a network cable. If you are using a laptop, it is strongly recommended to prohibit the WIFI network of the laptop during the test, and all kinds of agent software and virtual network cards are temporarily closed. After the test, open it one by one to see if there is a problem.

For the fixed IP mode, it can also be connected to the router or switch for test. Pay special attention to that the IP address set on the board does not conflict with the IP of other devices on the router or switch. In the test stage, it is still recommended to use the computer direct connection mode, and then run other modes after running through.

In the file demo_ dm9162_ netx. Set the IP address in H, and the specific configuration is as follows (you can update your own situation and modify it):

/*
*********************************************************************************************************
*                                        IP relevant
*********************************************************************************************************
*/
#define DEFAULT_PORT                    1001    /* TCP Server listening port number */

#define IP_ADDR0                        192
#define IP_ADDR1                        168
#define IP_ADDR2                        28
#define IP_ADDR3                        245     

8.4.4} step 2: set the IP address of the computer

The IP address of the computer must be set to the same IP segment as the development board, that is, 192.168.28 X. In step 2, the IP of the development board has been set to 192.168.28.245. Here, we will set the IP of the computer to 192.168.28.221. This is WIN7 64bit system.

(1) Right click the "network" icon on the desktop and select properties.

(2) Select "local connection" in the pop-up interface

(3) Select Properties

(4) Double click the Internet Protocol version 4(TCP/Ipv4) option.

(5) Configure IP address, subnet mask and default gateway. DNS does not need to be configured.

(6) After clicking the "OK" button, return to the previous interface. Don't forget to click the "OK" button here:

8.4.5 step 3: test whether the ping is successful

Download the routine to the development board, and then ping 192.168.28.245 to see if it is connected.

(1) Press WIN+R to open the "run" window and enter cmd.

(2) Enter ping 192.168.28.245 and press enter.

The sending and receiving are the same, and there is no data loss, indicating that the ping command is also successful.

8.4.6} step 3: the network debugging assistant creates a TCP client

  • Open the debugging assistant and click the upper left corner to create a connection:

  • The following interface pops up. Select TCP as the type, set the target IP to 192.168.28.245, and the port number is 1001. Finally, click Create:

  • The interface effect after creation is as follows:

  • Click Connect. The interface effect after connection is as follows:

8.4.7} step 5: TCP server loopback test

After the board and the network debugging assistant establish a connection, they can send and receive data from each other.

Sending and receiving are consistent, indicating that the migration is no problem.

8.5 experimental routine

Supporting examples:

V7-2402_ThreadX NetXDUO TCP Server

Purpose of the experiment:

  1. Learn the implementation of ThreadX NetXDUO TCP Server

Experiment content:

  1. The following tasks are created. You can print the usage of the task stack through the serial port by pressing the key K1

          ======================================================

        OS CPU Usage =  1.31%          

        =======================================================

Task priority task stack size current stack used  maximum stack used  task name

           Prio     StackSize   CurStack    MaxStack   Taskname

           2         4092        303         459      App Task Start

           30         1020        303         303      App Task STAT

           31         1020        87          71      App Task IDLE

           5          4092        311         551      App Msp Pro

           7         4092        303         719      App Task UserIF

           6         4092        255         359      App NETX Pro

           3         4092        415         535      NetX IP Instance 0

           0         1020        191         235      System Timer Thread   

Serial port software can use SecureCRT or H7-TOOL RTT to view print information.

App Task Start task: start the task, which is used here as a BSP driver package.

App Task MspPro task: message processing.

App Task UserIF task: key message processing.

App Task COM task: used here as LED flashing.

System Timer Thread task: system timer task

Operating instructions:

  1. Since the program uses the DWT clock cycle counter, please power on the board again after downloading the program to prevent the DWT clock cycle counter from being reset normally.
  2. NetX network protocol stack operation:

(1) The default IP address is 192.168.28.245, which is displayed in the demo_dm9162_netx.c, which can be modified as needed.

(2) You can create a TCP Client on the computer side with network debugging software to connect to the server side with port number 1001.

(3) A simple loop communication is realized. The data sent by the user is returned to the host computer through the board.

Serial port printing information mode (AC5, AC6 and IAR):

Baud rate 115200, data bit 8, parity bit none, stop bit 1

 

8.6 summary

This chapter mainly explains the implementation of TCP server for you. You can also create various playing methods to strengthen your understanding.