图52.3.1.1 程序流程图
52.3.2 程序解析
在本章节中,我们主要关注两个文件:lwip_demo.c和lwip_demo.h。lwip_demo.h文件主要定义了发送标志位并声明了lwip_demo函数,这部分相对简单,所以我们暂不详细解释。主要关注点是lwip_demo.c文件中的函数。在lwip_demo函数中,我们配置了相关的UDP参数,并创建了一个名为lwip_send_thread的发送数据线程。这个线程通过调用scokec函数来发送数据到服务器。接下来,我们将分别详细解释lwip_demo函数和lwip_send_thread任务。
/* 需要自己设置远程IP地址 */
#define IP_ADDR "192.168.101.33"
#define LWIP_DEMO_RX_BUFSIZE 200 /* 最大接收数据长度 */
#define LWIP_DEMO_PORT 8080 /* 连接的本地端口号 */
#define LWIP_SEND_THREAD_PRIO ( tskIDLE_PRIORITY + 3 ) /* 发送数据线程优先级 */
/* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];
/* 发送数据内容 */
char g_lwip_demo_sendbuf[] = "ALIENTEK DATA \r\n";
/* 数据发送标志位 */
uint8_t g_lwip_send_flag;
static struct sockaddr_in dest_addr; /* 远端地址 */ struct sockaddr_in g_local_info;
socklen_t g_sock_fd; /* 定义一个Socket接口 */
static void lwip_send_thread(void *arg);
extern QueueHandle_t g_display_queue; /* 显示消息队列句柄 */
/**
* @retval 无
*/
void lwip_data_send(void)
{
xTaskCreate(lwip_send_thread, "lwip_send_thread", 4096,
NULL, LWIP_SEND_THREAD_PRIO, NULL);
}
/**
* @brief lwip_demo实验入口
* @param 无
* @retval 无
*/
void lwip_demo(void)
{
char *tbuf;
lwip_data_send(); /* 创建发送数据线程 */
/* 远端参数设置 */
dest_addr.sin_addr.s_addr = inet_addr(IP_ADDR); /* 目标地址 */
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(LWIP_DEMO_PORT); /* 目标端口 */
g_local_info.sin_family = AF_INET; /* IPv4地址 */
g_local_info.sin_port = htons(LWIP_DEMO_PORT); /* 设置端口号 */
g_local_info.sin_addr.s_addr = htons(INADDR_ANY); /* 设置本地IP地址 */
g_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); /* 建立一个新的socket连接 */
tbuf = malloc(200); /* 申请内存 */
sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT); /* 客户端端口号 */
lcd_show_string(0, 170, 200, 16, 16, tbuf, MAGENTA);
/* 建立绑定 */
bind(g_sock_fd, (struct sockaddr *)&g_local_info, sizeof(g_local_info));
while (1)
{
memset(g_lwip_demo_recvbuf, 0, sizeof(g_lwip_demo_recvbuf));
recv(g_sock_fd, (void *)g_lwip_demo_recvbuf,
sizeof(g_lwip_demo_recvbuf), 0);
printf("%s\r\n",g_lwip_demo_recvbuf);
}
}
/**
* @brief 发送数据线程函数
* @param pvParameters : 传入参数(未用到)
* @retval 无
*/
void lwip_send_thread(void *pvParameters)
{
pvParameters = pvParameters;
while (1)
{ /* 有数据要发送 */
if ((g_lwip_send_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA)
{
printf("send\r\n");
sendto(g_sock_fd, /* scoket */
(char *)g_lwip_demo_sendbuf, /* 发送的数据 */
sizeof(g_lwip_demo_sendbuf), 0, /* 发送的数据大小 */
(struct sockaddr *)&dest_addr, /* 接收端地址信息 */
sizeof(dest_addr)); /* 接收端地址信息大小 */
g_lwip_send_flag &= ~LWIP_SEND_DATA;
}
vTaskDelay(100);
}
}
在源码中,lwip_demo函数通过lwip_data_send创建了发送数据的线程lwip_send_thread,并配置了Socket的UDP协议。该线程在发送前会检查标志位,有效时则通过sendto发送数据并重置标志位。同时,需设置目标IP地址以确保数据正确发送。此外,主函数的循环中不断通过recv接收数据并使用串口输出接收的数据。
52.4 下载验证
在程序中,首先需要设置好能够连接的网络账号和密码。然后,使用笔记本电脑作为终端,确保它与ESP32-S3设备处于同一网络段内。当ESP32-S3设备成功连接到网络时,它的LCD显示屏上会显示相应的内容:
图52.4.1 设备连接到网络时,LCD显示的信息
打开网络调试助手,然后配置网络参数,如UDP协议、端口号、目标主机设置等,设置内容如下图所示。
在确保网络连接正常后,可以通过按下开发板上的KEY0按键来发送数据至网络调试助手。当网络调试助手接收到“ALIENTEK DATA”字符串时,它会在显示区域展示这个信息。此外,用户还可以在调试助手的发送区域自行输入要发送的数据,然后点击发送键,将数据发送至ESP32-S3设备。此时,ESP32-S3的串口将打印接收到的数据,具体操作和输出如下图所示。