From 9230e7985d2fa055cb2feb0a9f6a375c17c29b4f Mon Sep 17 00:00:00 2001 From: zhoujie <929834232@qq.com> Date: Sat, 14 Mar 2026 21:31:44 +0800 Subject: [PATCH] 21 --- .../Middle/QDXnetworkStack/qdx_port.c | 48 ++++++++++++++----- prj/TCPClient/User/main.c | 11 ++++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/prj/TCPClient/Middle/QDXnetworkStack/qdx_port.c b/prj/TCPClient/Middle/QDXnetworkStack/qdx_port.c index 2836ff1..f5ab1fa 100644 --- a/prj/TCPClient/Middle/QDXnetworkStack/qdx_port.c +++ b/prj/TCPClient/Middle/QDXnetworkStack/qdx_port.c @@ -331,7 +331,7 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port) if (err != WCHNET_ERR_SUCCESS) { DBG_PORT("SocketConnect fail %02X\r\n", err); - WCHNET_SocketClose(wchnet_id, 0); + WCHNET_SocketClose(wchnet_id, TCP_CLOSE_RST); free_sock_ctx(ctx); return NULL; } @@ -346,14 +346,14 @@ qdx_socket_t qdx_port_tcp_connect(const char *ip, uint16_t port) DBG_PORT("connect_sem TIMEOUT after %d ms -> %d.%d.%d.%d:%d\r\n", (int)elapsed, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], port); DBG_PORT(" ctx->connected=%d wchnet_id=%d\r\n", ctx->connected, wchnet_id); - WCHNET_SocketClose(wchnet_id, 0); + WCHNET_SocketClose(wchnet_id, TCP_CLOSE_RST); free_sock_ctx(ctx); return NULL; } DBG_PORT("connect_sem got after %d ms, connected=%d\r\n", (int)elapsed, ctx->connected); if (!ctx->connected) { - WCHNET_SocketClose(wchnet_id, 0); + WCHNET_SocketClose(wchnet_id, TCP_CLOSE_RST); free_sock_ctx(ctx); return NULL; } @@ -373,16 +373,39 @@ int32_t qdx_port_tcp_send(qdx_socket_t sock, const uint8_t *data, uint32_t len) if (!ctx || !ctx->connected) return -1; - uint32_t send_len = len; + uint32_t total_sent = 0; + const uint8_t *ptr = data; + uint32_t remaining = len; + uint8_t retries = 0; - xSemaphoreTake(g_wchnet_mutex, portMAX_DELAY); - uint8_t err = WCHNET_SocketSend(ctx->wchnet_sock_id, (uint8_t *)data, &send_len); - xSemaphoreGive(g_wchnet_mutex); + while (remaining > 0) { + uint32_t send_len = remaining; - if (err != WCHNET_ERR_SUCCESS) - return -1; + xSemaphoreTake(g_wchnet_mutex, portMAX_DELAY); + uint8_t err = WCHNET_SocketSend(ctx->wchnet_sock_id, (uint8_t *)ptr, &send_len); + xSemaphoreGive(g_wchnet_mutex); - return (int32_t)send_len; + if (err != WCHNET_ERR_SUCCESS && send_len == 0) { + /* WCHNET send buffer full — yield so wchnet task can flush */ + if (++retries > 50) { + DBG_PORT("send fail after retries, err=0x%02X\r\n", err); + return -1; + } + vTaskDelay(pdMS_TO_TICKS(2)); + continue; + } + retries = 0; + ptr += send_len; + remaining -= send_len; + total_sent += send_len; + + if (remaining > 0) { + /* Partial send — yield to let wchnet task drain the buffer */ + vTaskDelay(pdMS_TO_TICKS(2)); + } + } + + return (int32_t)total_sent; } int32_t qdx_port_tcp_recv(qdx_socket_t sock, uint8_t *buf, uint32_t max_len) @@ -422,7 +445,10 @@ void qdx_port_tcp_close(qdx_socket_t sock) if (ctx->in_use) { xSemaphoreTake(g_wchnet_mutex, portMAX_DELAY); - WCHNET_SocketClose(ctx->wchnet_sock_id, 0); + /* Use TCP_CLOSE_RST to immediately release the WCHNET socket slot. + * TCP_CLOSE_NORMAL (0) causes TIME_WAIT which holds the slot for + * an extended period, preventing reconnection with only 2 sockets. */ + WCHNET_SocketClose(ctx->wchnet_sock_id, TCP_CLOSE_RST); xSemaphoreGive(g_wchnet_mutex); } ring_init(&ctx->rx_ring); diff --git a/prj/TCPClient/User/main.c b/prj/TCPClient/User/main.c index dc1c22d..b3ac74f 100644 --- a/prj/TCPClient/User/main.c +++ b/prj/TCPClient/User/main.c @@ -489,14 +489,21 @@ static void task_business_entry(void *pvParameters) else if (Preprocess_CheckInternalTrigger2D(&raw_img) == 1) { /* Trigger hit! Start burst: this frame is frame #0 */ + DBG_APP("TRIGGER frm=%d\r\n", (int)raw_img.FrameNumber); PreprocessResult_t meta; TcpTxBuffer_t *tx_buf = use_buffer_A ? &g_TxNetBuffer_A : &g_TxNetBuffer_B; use_buffer_A = !use_buffer_A; tx_buf->ValidPayloadLen = 0; - if (Preprocess_Execute(&raw_img, tx_buf, &meta) == 0) + int8_t pp_ret = Preprocess_Execute(&raw_img, tx_buf, &meta); + if (pp_ret == 0) { - TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 0x01, 1); + int8_t tx_ret = TcpLogic_BuildAndSendTemperatureFrame(tx_buf, &meta, 0x01, 1); + DBG_APP("SEND frm=%d %dx%d ret=%d\r\n", + (int)meta.FrameNumber, (int)meta.ValidWidth, + (int)meta.ValidHeight, (int)tx_ret); + } else { + DBG_APP("PP fail ret=%d\r\n", (int)pp_ret); } /* Determine burst count from config */