fix(tcp): MUX模式网口失联 — 对端关闭时用tcp_abort替代tcp_close避免TIME_WAIT耗尽pcb池
根因: tcp_close()将对端关闭的pcb推入TIME_WAIT(120s), 占用MEMP_TCP_PCB池(仅4个), 多连接同时断开后pcb池耗尽, tcp_new()返回NULL, 新连接无法建立直到120s超时释放。 核心修复: - tcp_server/client: 对端关闭(p=NULL)时tcp_abort替代tcp_close, pcb立即释放 - ch390_runtime: PKT_ERR恢复强制OR上RCR_RXEN(与WCH官方一致) - ch390_runtime: TX连续超时3次自动emergency reset - ch390_runtime: 每5秒health_check读VID验证芯片存活 - main: App_StartLinksIfNeeded失败时不标记g_links_started, 允许重试 - main: MUX逐帧RTT printf改为#if DEBUG门控, 减少主循环延迟 - uart_trans: MUX帧解析改为先搜0x7E再消费header, 非法帧只丢1字节
This commit is contained in:
+28
-2
@@ -39,6 +39,7 @@
|
||||
#define LED_PORT GPIOC
|
||||
#define APP_ROUTE_BUFFER_SIZE 256u
|
||||
#define STACK_GUARD_WORD 0xA5A5A5A5u
|
||||
#define APP_HEALTH_CHECK_INTERVAL_MS 5000u
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
@@ -175,15 +176,27 @@ static void App_ConfigureLinks(const device_config_t *cfg)
|
||||
|
||||
static void App_StartLinksIfNeeded(void)
|
||||
{
|
||||
int any_failed;
|
||||
|
||||
if ((g_links_started != 0u) || !netif_is_link_up(&ch390_netif)) {
|
||||
return;
|
||||
}
|
||||
|
||||
any_failed = 0;
|
||||
for (uint8_t i = 0; i < TCP_SERVER_INSTANCE_COUNT; ++i) {
|
||||
(void)tcp_server_start(i);
|
||||
if (tcp_server_start(i) != 0) {
|
||||
any_failed = 1;
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 0; i < TCP_CLIENT_INSTANCE_COUNT; ++i) {
|
||||
(void)tcp_client_connect(i);
|
||||
if (tcp_client_connect(i) != 0) {
|
||||
any_failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (any_failed) {
|
||||
SEGGER_RTT_WriteString(0, "NET links start partially failed, will retry\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_links_started = 1u;
|
||||
@@ -343,7 +356,9 @@ static void App_RouteMuxUartTraffic(void)
|
||||
const device_config_t *cfg = config_get();
|
||||
|
||||
while (uart_mux_try_extract_frame(UART_CHANNEL_U0, &frame)) {
|
||||
#if defined(DEBUG) && (DEBUG != 0)
|
||||
SEGGER_RTT_printf(0, "Mux frame from UART0: src_id=%u dst_mask=0x%02X len=%u\r\n", frame.src_id, frame.dst_mask, frame.payload_len);
|
||||
#endif
|
||||
if (frame.dst_mask == 0u) {
|
||||
at_result_t result;
|
||||
char *response_text = (char *)&g_mux_response_frame[5];
|
||||
@@ -382,7 +397,9 @@ static void App_RouteMuxUartTraffic(void)
|
||||
}
|
||||
|
||||
while (uart_mux_try_extract_frame(UART_CHANNEL_U1, &frame)) {
|
||||
#if defined(DEBUG) && (DEBUG != 0)
|
||||
SEGGER_RTT_printf(0, "Mux frame from UART1: src_id=%u dst_mask=0x%02X len=%u\r\n", frame.src_id, frame.dst_mask, frame.payload_len);
|
||||
#endif
|
||||
if (frame.dst_mask == 0u) {
|
||||
at_result_t result;
|
||||
char *response_text = (char *)&g_mux_response_frame[5];
|
||||
@@ -423,6 +440,9 @@ static void App_RouteMuxUartTraffic(void)
|
||||
|
||||
static void App_Poll(void)
|
||||
{
|
||||
static uint32_t s_health_check_tick;
|
||||
uint32_t now;
|
||||
|
||||
ethernetif_poll();
|
||||
ethernetif_check_link();
|
||||
sys_check_timeouts();
|
||||
@@ -440,6 +460,12 @@ static void App_Poll(void)
|
||||
App_RouteRawUartTraffic();
|
||||
}
|
||||
|
||||
now = HAL_GetTick();
|
||||
if ((now - s_health_check_tick) >= APP_HEALTH_CHECK_INTERVAL_MS) {
|
||||
s_health_check_tick = now;
|
||||
ch390_runtime_health_check(&ch390_netif);
|
||||
}
|
||||
|
||||
if (config_is_reset_requested()) {
|
||||
config_clear_reset_requested();
|
||||
NVIC_SystemReset();
|
||||
|
||||
Reference in New Issue
Block a user