fix: stop network tasks cleanly on restart

This commit is contained in:
2026-04-29 04:36:01 +08:00
parent ac0c464910
commit 60d2af0a27
4 changed files with 214 additions and 12 deletions
+71 -7
View File
@@ -14,7 +14,31 @@
#include "ethernetif.h"
#include "route_msg.h"
#define TCP_CLIENT_CONNECT_TIMEOUT_MS 5000
#define TCP_CLIENT_CONNECT_TIMEOUT_MS 500
#define TCP_CLIENT_STOP_POLL_MS 50u
static BaseType_t tcp_client_stop_requested(void)
{
return (app_network_task_stop_requested() != pdFALSE) ? pdTRUE : pdFALSE;
}
static BaseType_t tcp_client_delay_with_stop(uint32_t delay_ms)
{
uint32_t remaining_ms = delay_ms;
while (remaining_ms > 0u) {
uint32_t slice_ms = (remaining_ms > TCP_CLIENT_STOP_POLL_MS) ? TCP_CLIENT_STOP_POLL_MS : remaining_ms;
if (tcp_client_stop_requested() != pdFALSE) {
return pdFALSE;
}
vTaskDelay(pdMS_TO_TICKS(slice_ms));
remaining_ms -= slice_ms;
}
return (tcp_client_stop_requested() == pdFALSE) ? pdTRUE : pdFALSE;
}
static void tcp_client_abort_and_delete(struct netconn *conn, uint8_t link_index)
{
@@ -53,6 +77,10 @@ static err_t tcp_client_worker(struct netconn *conn, uint8_t link_index)
netconn_set_recvtimeout(conn, 10);
for (;;) {
if (tcp_client_stop_requested() != pdFALSE) {
return ERR_CLSD;
}
err = netconn_recv(conn, &buf);
if (err == ERR_OK) {
do {
@@ -76,11 +104,19 @@ static err_t tcp_client_worker(struct netconn *conn, uint8_t link_index)
}
} while (netbuf_next(buf) >= 0);
netbuf_delete(buf);
} else if (err != ERR_TIMEOUT) {
} else if (err == ERR_TIMEOUT) {
if (tcp_client_stop_requested() != pdFALSE) {
return ERR_CLSD;
}
} else {
return err;
}
while (xQueueReceive(xLinkTxQueues[link_index], &tx_msg, 0) == pdPASS) {
if (tcp_client_stop_requested() != pdFALSE) {
route_msg_free(tx_msg);
return ERR_CLSD;
}
err = netconn_write(conn, tx_msg->data, tx_msg->len, NETCONN_COPY);
route_msg_free(tx_msg);
if (err != ERR_OK) {
@@ -104,13 +140,25 @@ static void tcp_client_task(uint8_t link_index)
first_connect_deferred = (link_index == CONFIG_LINK_C1) ? 1u : 0u;
for (;;) {
if (tcp_client_stop_requested() != pdFALSE) {
break;
}
while ((g_netif_ready == pdFALSE) || (ethernetif_link_is_up() == 0u)) {
if (tcp_client_stop_requested() != pdFALSE) {
goto exit_task;
}
vTaskDelay(pdMS_TO_TICKS(100));
}
cfg = config_get();
if (cfg->links[link_index].enabled == 0u) {
vTaskDelay(pdMS_TO_TICKS(500));
if (tcp_client_stop_requested() != pdFALSE) {
break;
}
if (tcp_client_delay_with_stop(500u) == pdFALSE) {
break;
}
continue;
}
@@ -119,13 +167,17 @@ static void tcp_client_task(uint8_t link_index)
if (first_connect_deferred != 0u) {
first_connect_deferred = 0u;
debug_log_write("[CLI] C1 first-connect defer\r\n");
vTaskDelay(pdMS_TO_TICKS(delay_ms));
if (tcp_client_delay_with_stop(delay_ms) == pdFALSE) {
break;
}
continue;
}
conn = netconn_new(NETCONN_TCP);
if (conn == NULL) {
vTaskDelay(pdMS_TO_TICKS(delay_ms));
if (tcp_client_delay_with_stop(delay_ms) == pdFALSE) {
break;
}
continue;
}
@@ -137,7 +189,9 @@ static void tcp_client_task(uint8_t link_index)
(int)err,
(unsigned int)cfg->links[link_index].local_port);
netconn_delete(conn);
vTaskDelay(pdMS_TO_TICKS(delay_ms));
if (tcp_client_delay_with_stop(delay_ms) == pdFALSE) {
break;
}
continue;
}
}
@@ -176,8 +230,18 @@ static void tcp_client_task(uint8_t link_index)
}
tcp_client_abort_and_delete(conn, link_index);
vTaskDelay(pdMS_TO_TICKS(delay_ms));
if (tcp_client_stop_requested() != pdFALSE) {
break;
}
if (tcp_client_delay_with_stop(delay_ms) == pdFALSE) {
break;
}
}
exit_task:
netconn_thread_cleanup();
app_on_network_task_exit(xTaskGetCurrentTaskHandle());
vTaskDelete(NULL);
}
void TcpCliTask_C1(void *argument)