/****************************************************************************** 版权所有 (C), 2018-2099, Radkil ****************************************************************************** 文 件 名 : My_Lwip.c 版 本 号 : 初稿 作 者 : Radkil 生成日期 : 2026年5月21日 最近修改 : 功能描述 : LWIP中间层 修改历史 : 1.日 期 : 2026年5月21日 作 者 : Radkil 修改内容 : 创建文件 ******************************************************************************/ #include "bsp_config.h" #ifdef USE_LWIP #include "lwip/sockets.h" #include "lwip/netdb.h" #include "FreeRTOS.h" #include "task.h" #include #include #include "common.h" #include "ringbuffer.h" #include "semphr.h" #include "lua_base.h" #include /*----------------------------------------------* * 外部变量说明 * *----------------------------------------------*/ /*----------------------------------------------* * 外部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 内部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 全局变量 * *----------------------------------------------*/ /*----------------------------------------------* * 模块级变量 * *----------------------------------------------*/ /*----------------------------------------------* * 常量定义 * *----------------------------------------------*/ /*----------------------------------------------* * 宏定义 * *----------------------------------------------*/ #define PORT 23 // 监听的端口号 #define RECV_SIZE 256 // 接收缓冲区大小 static int connect_fd = -1; //socket套接字 #if 0 static rd_ringbuf_t *g_rb_handle = NULL; SemaphoreHandle_t xSemaphore; StaticSemaphore_t xSemaphoreBuffer; SemaphoreHandle_t xMutex; StaticSemaphore_t xMutexBuffer; void Myprint_Init(void) { g_rb_handle = rd_RingbufferCreate(RECV_SIZE); rd_RingbufferReset(g_rb_handle); xSemaphore = xSemaphoreCreateCountingStatic(5, 0, &xSemaphoreBuffer); xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer); return; } void Myprint_timer(void) { return; } void Myprint_IRQHandler(void) { return; } int Myprint_putchar(uint8_t ch) { if (connect_fd < 0) return 0; char tx_buf[2]; if (ch == '\n') { tx_buf[0] = '\r'; tx_buf[1] = '\n'; if (write(connect_fd, tx_buf, 2) < 0) return EOF; return 2; } else { tx_buf[0] = ch; if (write(connect_fd, tx_buf, 1) < 0) return EOF; return 1; } } void Myprint_getchar(char *ch) { while (1) { int ret; if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) { if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) { ret = rd_RingbufferGet(g_rb_handle, ch, 1); xSemaphoreGive(xMutex); if (ret > 0) { return; } } } } } #endif void ShowLWIPstate(void) { stats_display(); } void luaprint_talnet(const char *fmt, ...) { char temp[RECV_SIZE]; va_list args; va_start(args, fmt); vsprintf(temp, fmt, args); write(connect_fd, &temp, strlen(temp)); va_end(args); } void vTCPServer_Task(void *pvParameters) { int listen_fd; struct sockaddr_in server_addr, client_addr; char temp[RECV_SIZE]; int ret; socklen_t addr_len = sizeof(struct sockaddr_in); // 1. 创建 socket (AF_INET表示IPv4, SOCK_STREAM表示TCP) listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { log_e("Socket create failed!\r\n"); vTaskDelete(NULL); return; } // 2. 绑定 IP 和端口 (INADDR_ANY 表示绑定本地所有网卡IP) memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { log_e("Bind failed!\r\n"); close(listen_fd); vTaskDelete(NULL); return; } // 3. 开始监听,最大排队连接数为 5 if (listen(listen_fd, 5) < 0) { log_e("Listen failed!\r\n"); close(listen_fd); vTaskDelete(NULL); return; } log_i("TCP Server is running on port %d...\r\n", PORT); while (1) { // 4. 阻塞等待客户端连接 connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addr_len); if (connect_fd < 0) { log_w("Accept failed!\r\n"); continue; } #ifdef USE_TALNET lua_init(luaprint_talnet); #endif // // 第一条指令:要求客户端关闭本地回显,交由服务器处理 // unsigned char cmd_echo[] = { 255, 254, 1 }; // // IAC(255) DO(253) ECHO(1) // // // 第二条指令:禁用“前进抑制”,强制进入实时字符流模式 // unsigned char cmd_sga[] = { 255, 254, 3 }; // // IAC(255) DO(253) SUPPRESS-GO-AHEAD(3) // // write(connect_fd, cmd_echo, sizeof(cmd_echo)); // write(connect_fd, cmd_sga, sizeof(cmd_sga)); // int enable = 1; // 1 表示启用 TCP_NODELAY(即禁用 Nagle 算法) // setsockopt(connect_fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); // 打印连接的客户端 IP 和端口 log_i("New client connected: %s:%d\r\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 5. 循环接收并回显数据 // char *welcome = "\n> "; // write(connect_fd, welcome, strlen(welcome)); while (1) { // 阻塞接收数据 ret = read(connect_fd, &temp, RECV_SIZE); if (ret > 0) { #ifdef USE_TALNET lua_repl(temp, ret, 0); #else write(connect_fd, temp, ret); #endif #if 0 if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) { int iLen = rd_RingbufferPutForce(g_rb_handle, &temp, ret); xSemaphoreGive(xMutex); if (iLen > 0) { xSemaphoreGive(xSemaphore); } } #endif } else if (ret == 0) { // 客户端正常断开连接 log_i("Client disconnected.\r\n"); break; } else { // 接收出错 log_e("Read data error!\r\n"); break; } } // 关闭与当前客户端的连接 close(connect_fd); } } #endif