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:
@@ -38,6 +38,14 @@ static uint8_t ch390_runtime_drain_rx(struct netif *netif, uint8_t max_frames)
|
||||
static volatile uint8_t g_ch390_irq_pending;
|
||||
static uint8_t g_ch390_ready;
|
||||
static ch390_diag_t g_diag;
|
||||
static uint8_t g_tx_consecutive_timeout;
|
||||
static uint8_t g_chip_reset_count;
|
||||
|
||||
#define TX_TIMEOUT_THRESHOLD 3u
|
||||
#define CHIP_RESET_MAX 3u
|
||||
|
||||
#define TX_TIMEOUT_THRESHOLD 3u
|
||||
#define CHIP_RESET_MAX 3u
|
||||
|
||||
static uint8_t ch390_runtime_probe_identity(void)
|
||||
{
|
||||
@@ -99,7 +107,7 @@ struct pbuf *ch390_runtime_input_frame(struct netif *netif)
|
||||
ch390_write_reg(CH390_MPTRCR, 0x01u);
|
||||
ch390_write_reg(CH390_MRRH, 0x0Cu);
|
||||
ch390_delay_us(1000u);
|
||||
ch390_write_reg(CH390_RCR, rcr);
|
||||
ch390_write_reg(CH390_RCR, (uint8_t)(rcr | RCR_RXEN));
|
||||
ethernetif->rx_len = 0u;
|
||||
LINK_STATS_INC(link.drop);
|
||||
g_diag.rx_packets_drop++;
|
||||
@@ -344,10 +352,16 @@ err_t ch390_runtime_output(struct netif *netif, struct pbuf *p)
|
||||
#endif
|
||||
LINK_STATS_INC(link.drop);
|
||||
g_diag.tx_packets_timeout++;
|
||||
g_tx_consecutive_timeout++;
|
||||
if (g_tx_consecutive_timeout >= TX_TIMEOUT_THRESHOLD) {
|
||||
ch390_runtime_emergency_reset();
|
||||
}
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
g_tx_consecutive_timeout = 0u;
|
||||
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
ch390_write_mem((uint8_t *)q->payload, q->len);
|
||||
}
|
||||
@@ -377,3 +391,55 @@ bool ch390_runtime_is_ready(void)
|
||||
{
|
||||
return g_ch390_ready != 0u;
|
||||
}
|
||||
|
||||
bool ch390_runtime_emergency_reset(void)
|
||||
{
|
||||
SEGGER_RTT_printf(0, "ETH emergency reset (tx_timeout=%u resets=%u/%u)\r\n",
|
||||
g_tx_consecutive_timeout, g_chip_reset_count, CHIP_RESET_MAX);
|
||||
|
||||
if (g_chip_reset_count >= CHIP_RESET_MAX) {
|
||||
SEGGER_RTT_WriteString(0, "ETH: max resets reached, giving up\r\n");
|
||||
g_ch390_ready = 0u;
|
||||
return false;
|
||||
}
|
||||
|
||||
g_chip_reset_count++;
|
||||
g_tx_consecutive_timeout = 0u;
|
||||
|
||||
ch390_software_reset();
|
||||
ch390_delay_us(5000u);
|
||||
ch390_default_config();
|
||||
|
||||
ch390_runtime_refresh_diag();
|
||||
g_ch390_ready = g_diag.id_valid;
|
||||
|
||||
if (g_ch390_ready == 0u) {
|
||||
SEGGER_RTT_WriteString(0, "ETH emergency reset: chip not responding\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SEGGER_RTT_WriteString(0, "ETH emergency reset: OK\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void ch390_runtime_health_check(struct netif *netif)
|
||||
{
|
||||
if (!g_ch390_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify chip is still responding by reading vendor ID */
|
||||
uint16_t vid = ch390_get_vendor_id();
|
||||
if (vid == 0x0000u || vid == 0xFFFFu) {
|
||||
SEGGER_RTT_printf(0, "ETH health: invalid VID=0x%04X, attempting reset\r\n", vid);
|
||||
netif_set_link_down(netif);
|
||||
if (ch390_runtime_emergency_reset()) {
|
||||
ch390_runtime_check_link(netif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ch390_runtime_get_reset_count(void)
|
||||
{
|
||||
return g_chip_reset_count;
|
||||
}
|
||||
|
||||
@@ -58,5 +58,8 @@ void ch390_runtime_check_link(struct netif *netif);
|
||||
err_t ch390_runtime_output(struct netif *netif, struct pbuf *p);
|
||||
void ch390_runtime_get_diag(ch390_diag_t *diag);
|
||||
bool ch390_runtime_is_ready(void);
|
||||
bool ch390_runtime_emergency_reset(void);
|
||||
void ch390_runtime_health_check(struct netif *netif);
|
||||
uint8_t ch390_runtime_get_reset_count(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user