前言
代码
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-4-9 shchl first version
*/
#include "includes.h"
#define UDP_STACK_SIZE 4096 /*任务栈大小*/
#define UDP_PRIORITY 4 /*优先级*/
#define PACKET_SIZE 1536 /*数据包大小*/
#define POOL_SIZE ((sizeof(NX_PACKET) + PACKET_SIZE) * 16) /*数据包池大小(16个缓冲区)*/
#define LOCAL_IP IP_ADDRESS(192, 168, 8, 9) /*本地ip*/
#define LOCAL_PORT 8000
#define LOCAL_SUB_MASK IP_ADDRESS(255,255,255,0) /*本地ip*/
#define REMOTE_IP IP_ADDRESS(192, 168, 8, 2) /*远端*/
#define REMOTE_PORT 8000
TX_THREAD tcp_server_thread; /*tcp 服务线程*/
NX_TCP_SOCKET tcp_server_socket; /*服务端socket*/
static ULONG error_counter = 0; /*错误计数器(可用来排查问题出现位置)*/
/*
*******************************************************************************************************
* 外部引入变量
*******************************************************************************************************
*/
/*
*******************************************************************************************************
* 变量
*******************************************************************************************************
*/
/*
*********************************************************************************************************
* 静态全局变量
*********************************************************************************************************
*/
static TX_THREAD udp_thread;
static NX_IP local_ip; /*本地ip*/
static NX_PACKET_POOL packet_pool; /*数据包池*/
static NX_UDP_SOCKET udp_socket; /*数据包池*/
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
static void udp_thread_entry(ULONG input);
static inline void status_check(UINT stat);
/*
*********************************************************************************************************
* 外部函数
*********************************************************************************************************
*/
int app_task_udp_thread_create(void) {
UINT status;
/* Create the main thread. */
tx_thread_create(&udp_thread,
"thread 0",
udp_thread_entry,
0,
app_malloc(UDP_STACK_SIZE),
UDP_STACK_SIZE,
UDP_PRIORITY,
UDP_PRIORITY,
TX_NO_TIME_SLICE,
TX_AUTO_START);
/* Initialize the NetX system. */
nx_system_initialize();
/* Create a packet pool. */
status = nx_packet_pool_create(&packet_pool,
"NetX Main Packet Pool",
PACKET_SIZE,
app_malloc(POOL_SIZE),
POOL_SIZE);
/* Check for pool creation error. */
status_check(status);
/* Create an IP instance. */
status = nx_ip_create(&local_ip,
"NetX IP Instance 0",
LOCAL_IP,
LOCAL_SUB_MASK,
&packet_pool,
nx_stm32_eth_driver,
app_malloc(2048), 2048, 1);
/* Check for IP create errors. */
status_check(status);
/* Enable ARP and supply ARP cache memory for IP Instance 0. */
status = nx_arp_enable(&local_ip, app_malloc(1024), 1024);
/* Check for ARP enable errors. */
status_check(status);
/* Enable ICMP */
status = nxd_icmp_enable(&local_ip);
status_check(status);
/* Enable UDP traffic. */
status = nx_udp_enable(&local_ip);
/* Check for UDP enable errors. */
status_check(status);
return NX_SUCCESS;
}
NET_X_APP_EXPORT(app_task_udp_thread_create);
/*
*********************************************************************************************************
* 内部函数
*********************************************************************************************************
*/
static inline void status_check(UINT stat) {
if (stat) {
error_counter++;
// todo
}
}
static void udp_thread_entry(ULONG input) {
UINT status;
ULONG actual_status;
NX_PACKET *my_packet;
NXD_ADDRESS ipv4_address;
/* 确保 IP 实例已初始化。 */
do {
/* 等待 1 秒钟,让 内部 IP 线程完成其初始化。. */
status = nx_ip_status_check(&local_ip,
NX_IP_INITIALIZE_DONE,
&actual_status,
NX_IP_PERIODIC_RATE);
} while (status != NX_SUCCESS);
ipv4_address.nxd_ip_version = NX_IP_VERSION_V4;
ipv4_address.nxd_ip_address.v4 = REMOTE_IP;
/* Create a UDP socket. */
status = nx_udp_socket_create(&local_ip,
&udp_socket,
"Socket 0",
NX_IP_NORMAL,
NX_FRAGMENT_OKAY,
0x80,
5);
/* Check status. */
if (status) {
tx_log("nx_udp_socket_create error:%d\r\n", status);
error_counter++;
return;
}
/* Bind the UDP socket to the IP port. */
status = nx_udp_socket_bind(&udp_socket, LOCAL_PORT, TX_WAIT_FOREVER);
/* Check status. */
if (status) {
tx_log("nx_udp_socket_bind error:%d\r\n", status);
error_counter++;
return;
}
/* Disable checksum logic for this socket. */
nx_udp_socket_checksum_disable(&udp_socket);
/* Setup the ARP entry for the UDP send. */
nx_arp_dynamic_entry_set(&local_ip, REMOTE_IP, 0, 0);
while (1) {
/* Allocate a packet. */
status = nx_packet_allocate(&packet_pool,
&my_packet,
NX_UDP_PACKET,
TX_WAIT_FOREVER);
/* Check status. */
if (status != NX_SUCCESS) {
tx_log("nx_packet_allocate error:%d\r\n", status);
tx_thread_sleep(1000);
continue;
}
#define SEND_DATA "udp send test data"
/* Write ABCs into the packet payload! */
nx_packet_data_append(my_packet,
SEND_DATA,
sizeof(SEND_DATA),
&packet_pool, TX_WAIT_FOREVER);
/* Send the UDP packet. */
status = nxd_udp_socket_send(&udp_socket, my_packet, &ipv4_address, REMOTE_PORT);
/* Check status. */
if (status != NX_SUCCESS) {
error_counter++;
break;
}
tx_thread_sleep(500);
}
}