打印
[STM32H5]

【NUCLEO-H563ZI测评】5.NetXDuo UDP服务器

[复制链接]
703|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dami|  楼主 | 2023-8-17 00:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dami 于 2023-8-17 10:53 编辑

                        【NUCLEO-H563ZI测评】5.NetXDuo UDP服务器


玩了一下THREADX后,发现NetXDuo这个东西蛮好的,那不也得玩一下啊。

下载解压en.stm32cubeh5-v1-1-0。
mdk打开STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\Applications\NetXDuo\Nx_UDP_Echo_Server\MDK-ARM目录里的Nx_UDP_Echo_Server。


编译下载运行
连接串口和以太网口 串口显示如下


找一个udp的调试软件并创建一个客户端连接这个板子的服务器,发送数据,那边就收到了


主要代码在app_netxduo.c中
MX_NetXDuo_Init(VOID *memory_ptr)中创建各种任务

UINT MX_NetXDuo_Init(VOID *memory_ptr)
{
  UINT ret = NX_SUCCESS;
  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;
   /* USER CODE BEGIN App_NetXDuo_MEM_POOL */
  /* USER CODE END App_NetXDuo_MEM_POOL */
  /* USER CODE BEGIN 0 */
  printf("Nx_UDP_Echo_Server application started..\n");
  /* USER CODE END 0 */
  /* Initialize the NetXDuo system. */
  CHAR *pointer;
  nx_system_initialize();
    /* Allocate the memory for packet_pool.  */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, NX_APP_PACKET_POOL_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* Create the Packet pool to be used for packet allocation,
   * If extra NX_PACKET are to be used the NX_APP_PACKET_POOL_SIZE should be increased
   */
  ret = nx_packet_pool_create(&NxAppPool, "NetXDuo App Pool", DEFAULT_PAYLOAD_SIZE, pointer, NX_APP_PACKET_POOL_SIZE);
  if (ret != NX_SUCCESS)
  {
    return NX_POOL_ERROR;
  }
    /* Allocate the memory for Ip_Instance */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, Nx_IP_INSTANCE_THREAD_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
   /* Create the main NX_IP instance */
  ret = nx_ip_create(&NetXDuoEthIpInstance, "NetX Ip instance", NX_APP_DEFAULT_IP_ADDRESS, NX_APP_DEFAULT_NET_MASK, &NxAppPool, nx_stm32_eth_driver,
                     pointer, Nx_IP_INSTANCE_THREAD_SIZE, NX_APP_INSTANCE_PRIORITY);
  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }
    /* Allocate the memory for ARP */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, DEFAULT_ARP_CACHE_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* Enable the ARP protocol and provide the ARP cache size for the IP instance */
  /* USER CODE BEGIN ARP_Protocol_Initialization */
  /* USER CODE END ARP_Protocol_Initialization */
  ret = nx_arp_enable(&NetXDuoEthIpInstance, (VOID *)pointer, DEFAULT_ARP_CACHE_SIZE);
  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }
  /* Enable the ICMP */
  /* USER CODE BEGIN ICMP_Protocol_Initialization */
  /* USER CODE END ICMP_Protocol_Initialization */
  ret = nx_icmp_enable(&NetXDuoEthIpInstance);
  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }
  /* Enable TCP Protocol */
  /* USER CODE BEGIN TCP_Protocol_Initialization */
  /* USER CODE END TCP_Protocol_Initialization */
  ret = nx_tcp_enable(&NetXDuoEthIpInstance);
  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }
  /* Enable the UDP protocol required for  DHCP communication */
  /* USER CODE BEGIN UDP_Protocol_Initialization */
  /* USER CODE END UDP_Protocol_Initialization */
  ret = nx_udp_enable(&NetXDuoEthIpInstance);
  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }
   /* Allocate the memory for main thread   */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, NX_APP_THREAD_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* Create the main thread */
  ret = tx_thread_create(&NxAppThread, "NetXDuo App thread", App_Main_Thread_Entry , 0, pointer, NX_APP_THREAD_STACK_SIZE,
                         NX_APP_THREAD_PRIORITY, NX_APP_THREAD_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS)
  {
    return TX_THREAD_ERROR;
  }
  /* Create the DHCP client */
  /* USER CODE BEGIN DHCP_Protocol_Initialization */
  /* USER CODE END DHCP_Protocol_Initialization */
  ret = nx_dhcp_create(&DHCPClient, &NetXDuoEthIpInstance, "DHCP Client");
  if (ret != NX_SUCCESS)
  {
    return NX_DHCP_ERROR;
  }
  /* set DHCP notification callback  */
  tx_semaphore_create(&DHCPSemaphore, "DHCP Semaphore", 0);
  /* USER CODE BEGIN MX_NetXDuo_Init */
  /* Allocate the app UDP thread entry pool. */
  ret = tx_byte_allocate(byte_pool, (VOID **) &pointer, 2 * DEFAULT_MEMORY_SIZE, TX_NO_WAIT);
  if (ret != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* create the UDP server thread */
  ret = tx_thread_create(&AppUDPThread, "App UDP Thread", App_UDP_Thread_Entry, 0, pointer, 2 * DEFAULT_MEMORY_SIZE,
                        DEFAULT_PRIORITY, DEFAULT_PRIORITY, TX_NO_TIME_SLICE, TX_DONT_START);
  if (ret != TX_SUCCESS)
  {
    return TX_THREAD_ERROR;
  }
  /* Allocate the memory for Link thread   */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer,2 *  DEFAULT_MEMORY_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }
  /* create the Link thread */
  ret = tx_thread_create(&AppLinkThread, "App Link Thread", App_Link_Thread_Entry, 0, pointer, 2 * DEFAULT_MEMORY_SIZE,
                         LINK_PRIORITY, LINK_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS)
  {
    return TX_THREAD_ERROR;
  }
  /* USER CODE END MX_NetXDuo_Init */
  return ret;
}
相应的入口函数中处理

static VOID ip_address_change_notify_callback(NX_IP *ip_instance, VOID *ptr)
{
  /* USER CODE BEGIN ip_address_change_notify_callback */
  /* USER CODE END ip_address_change_notify_callback */
  /* release the semaphore as soon as an IP address is available */
  tx_semaphore_put(&DHCPSemaphore);
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  Main thread entry.
* @param thread_input: ULONG user argument used by the thread entry
* @retval none
*/
static VOID App_Main_Thread_Entry (ULONG thread_input)
{
  /* USER CODE BEGIN Nx_App_Thread_Entry 0 */
  /* USER CODE END Nx_App_Thread_Entry 0 */
  UINT ret = NX_SUCCESS;
  /* USER CODE BEGIN Nx_App_Thread_Entry 1 */
  /* USER CODE END Nx_App_Thread_Entry 1 */
  /* register the IP address change callback */
  ret = nx_ip_address_change_notify(&NetXDuoEthIpInstance, ip_address_change_notify_callback, NULL);
  if (ret != NX_SUCCESS)
  {
    /* USER CODE BEGIN IP address change callback error */
    Error_Handler();
    /* USER CODE END IP address change callback error */
  }
  /* start the DHCP client */
  ret = nx_dhcp_start(&DHCPClient);
  if (ret != NX_SUCCESS)
  {
    /* USER CODE BEGIN DHCP client start error */
    Error_Handler();
    /* USER CODE END DHCP client start error */
  }
  /* wait until an IP address is ready */
  if(tx_semaphore_get(&DHCPSemaphore, NX_APP_DEFAULT_TIMEOUT) != TX_SUCCESS)
  {
    /* USER CODE BEGIN DHCPSemaphore get error */
    Error_Handler();
    /* USER CODE END DHCPSemaphore get error */
  }
  /* USER CODE BEGIN Nx_App_Thread_Entry 2 */
  /* get IP address */
  ret = nx_ip_address_get(&NetXDuoEthIpInstance, &IpAddress, &NetMask);
  /* print the IP address */
  PRINT_IP_ADDRESS(IpAddress);
  if (ret != TX_SUCCESS)
  {
    Error_Handler();
  }
  /* Now the network is correctly initialized, start the UDP server thread */
  tx_thread_resume(&AppUDPThread);
  /* this thread is not needed any more, we relinquish it */
  tx_thread_relinquish();
  /* USER CODE END Nx_App_Thread_Entry 2 */
}
/* USER CODE BEGIN 1 */
static VOID App_UDP_Thread_Entry(ULONG thread_input)
{
  UINT ret;
  ULONG bytes_read;
  UINT source_port;
  UCHAR data_buffer[512];
  ULONG source_ip_address;
  NX_PACKET *data_packet;
  /* create the UDP socket */
  ret = nx_udp_socket_create(&NetXDuoEthIpInstance, &UDPSocket, "UDP Server Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, QUEUE_MAX_SIZE);
  if (ret != NX_SUCCESS)
  {
     Error_Handler();
  }
  /* bind the socket indefinitely on the required port */
  ret = nx_udp_socket_bind(&UDPSocket, DEFAULT_PORT, TX_WAIT_FOREVER);
  if (ret != NX_SUCCESS)
  {
     Error_Handler();
  }
  else
  {
    printf("UDP Server listening on PORT %d.. \n", DEFAULT_PORT);
  }
  while(1)
  {
    TX_MEMSET(data_buffer, '\0', sizeof(data_buffer));
    /* wait for data for 1 sec */
    ret = nx_udp_socket_receive(&UDPSocket, &data_packet, 100);
    if (ret == NX_SUCCESS)
    {
      /* data is available, read it into the data buffer */
      nx_packet_data_retrieve(data_packet, data_buffer, &bytes_read);
      /* get info about the client address and port */
      nx_udp_source_extract(data_packet, &source_ip_address, &source_port);
      /* print the client address, the remote port and the received data */
      PRINT_DATA(source_ip_address, source_port, data_buffer);
      /* resend the same packet to the client */
      ret =  nx_udp_socket_send(&UDPSocket, data_packet, source_ip_address, source_port);
      /* toggle the green led to monitor visually the traffic */
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    }
    else
    {
        /* the server is in idle state, toggle the green led */
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    }
  }
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  Link thread entry
* @param thread_input: ULONG thread parameter
* @retval none
*/
static VOID App_Link_Thread_Entry(ULONG thread_input)
{
  ULONG actual_status;
  UINT linkdown = 0, status;
  while(1)
  {
    /* Get Physical Link status. */
    status = nx_ip_interface_status_check(&NetXDuoEthIpInstance, 0, NX_IP_LINK_ENABLED,
                                      &actual_status, 10);
    if(status == NX_SUCCESS)
    {
      if(linkdown == 1)
      {
        linkdown = 0;
        status = nx_ip_interface_status_check(&NetXDuoEthIpInstance, 0, NX_IP_ADDRESS_RESOLVED,
                                      &actual_status, 10);
        if(status == NX_SUCCESS)
        {
          /* The network cable is connected again. */
          printf("The network cable is connected again.\n");
          /* Print UDP Echo Server is available again. */
          printf("UDP Echo Server is available again.\n");
        }
        else
        {
          /* The network cable is connected. */
          printf("The network cable is connected.\n");
          /* Send command to Enable Nx driver. */
          nx_ip_driver_direct_command(&NetXDuoEthIpInstance, NX_LINK_ENABLE,
                                      &actual_status);
          /* Restart DHCP Client. */
          nx_dhcp_stop(&DHCPClient);
          nx_dhcp_start(&DHCPClient);
        }
      }
    }
    else
    {
      if(0 == linkdown)
      {
        linkdown = 1;
        /* The network cable is not connected. */
        printf("The network cable is not connected.\n");
      }
    }
    tx_thread_sleep(NX_ETH_CABLE_CONNECTION_CHECK_PERIOD);
  }
}
/* USER CODE END 1 */



  

使用特权

评论回复
沙发
yangjiaxu| | 2024-1-12 16:40 | 只看该作者
我也想玩,最近玩网络玩的很嗨,我觉得很有意思

使用特权

评论回复
板凳
Allison8859| | 2024-1-12 16:41 | 只看该作者
UDP确实简单了一些,其实玩一些复杂的协议也是可以的了

使用特权

评论回复
地板
Candic12e| | 2024-1-12 16:41 | 只看该作者
这个和普通的lwip来说,有啥优势不?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

1050

帖子

6

粉丝