From d6a156550361e177fc8602cbc95a8b978c0b16ce Mon Sep 17 00:00:00 2001 From: xiao Date: Thu, 23 Apr 2026 18:06:02 +0800 Subject: [PATCH] fix: fail fast on app route backpressure --- App/config.c | 60 ++++++++++++++++++++++++++++++++++++++++-------- App/tcp_client.c | 23 +++++++++++++------ App/tcp_server.c | 29 +++++++++++++++-------- 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/App/config.c b/App/config.c index b2f337c..cd42cd1 100644 --- a/App/config.c +++ b/App/config.c @@ -22,6 +22,8 @@ static device_config_t g_config; static volatile bool g_reset_requested; static volatile bool g_uart1_tx_busy; +static volatile uint32_t g_config_rx_route_fail_count; +static volatile route_send_result_t g_config_rx_route_fail_reason; static uint8_t g_uart1_rx_buffer[CONFIG_RX_BUFFER_SIZE]; static char g_config_cmd_buffer[CONFIG_CMD_MAX_LEN]; static char g_config_response_buffer[CONFIG_TX_BUFFER_SIZE]; @@ -570,19 +572,24 @@ void config_uart_idle_handler(void) uint16_t len = CONFIG_RX_BUFFER_SIZE - dma_counter; BaseType_t xHigherPriorityTaskWoken = pdFALSE; HAL_StatusTypeDef hal_status; + route_send_result_t route_result; if (g_uart1_tx_busy) { return; } if (len > 0u && xConfigQueue != NULL) { - (void)route_send_from_isr(xConfigQueue, - 0u, - 0u, - ROUTE_CONN_UART1, - g_uart1_rx_buffer, - len, - &xHigherPriorityTaskWoken); + route_result = route_send_from_isr(xConfigQueue, + 0u, + 0u, + ROUTE_CONN_UART1, + g_uart1_rx_buffer, + len, + &xHigherPriorityTaskWoken); + if (route_result != ROUTE_SEND_OK) { + g_config_rx_route_fail_reason = route_result; + g_config_rx_route_fail_count += 1u; + } } hal_status = HAL_UART_DMAStop(&huart1); @@ -625,16 +632,47 @@ static void config_respond_to_uart(route_msg_t *msg, const char *response) uart_channel_t channel = (msg->src_id == ENDPOINT_UART3) ? UART_CHANNEL_U1 : UART_CHANNEL_U0; uint8_t frame[ROUTE_MSG_MAX_PAYLOAD + 6u]; uint16_t frame_len = 0u; + uart_trans_send_result_t uart_result; if (uart_mux_encode_frame(msg->src_id, 0u, (const uint8_t *)response, (uint16_t)strlen(response), frame, &frame_len, sizeof(frame))) { - (void)uart_trans_send_buffer(channel, frame, frame_len); + uart_result = uart_trans_send_buffer(channel, frame, frame_len); + if (uart_result != UART_TRANS_SEND_OK) { + debug_log_printf("[CFG] resp-tx-fail ch=%u rc=%s len=%u\r\n", + (unsigned int)channel, + uart_trans_send_result_to_str(uart_result), + (unsigned int)frame_len); + } + } else { + debug_log_printf("[CFG] resp-enc-fail src=0x%02X len=%u\r\n", + (unsigned int)msg->src_id, + (unsigned int)strlen(response)); } } } +static void config_report_route_failures(uint32_t *reported_route_fail_count) +{ + uint32_t fail_count; + route_send_result_t fail_reason; + + if (reported_route_fail_count == NULL) { + return; + } + + fail_count = g_config_rx_route_fail_count; + fail_reason = g_config_rx_route_fail_reason; + if (fail_count != *reported_route_fail_count) { + *reported_route_fail_count = fail_count; + debug_log_printf("[CFG] rx-route-fail rc=%s cnt=%lu\r\n", + route_send_result_to_str(fail_reason), + (unsigned long)fail_count); + } +} + void ConfigTask(void *argument) { route_msg_t *msg; at_result_t result; + uint32_t reported_route_fail_count = 0u; (void)argument; debug_log_write("[CFG] task-entry\r\n"); @@ -642,10 +680,14 @@ void ConfigTask(void *argument) debug_log_write("[CFG] task-ready\r\n"); for (;;) { - if (xQueueReceive(xConfigQueue, &msg, portMAX_DELAY) != pdPASS) { + config_report_route_failures(&reported_route_fail_count); + + if (xQueueReceive(xConfigQueue, &msg, pdMS_TO_TICKS(50)) != pdPASS) { continue; } + config_report_route_failures(&reported_route_fail_count); + if (msg->len >= sizeof(g_config_cmd_buffer)) { msg->len = sizeof(g_config_cmd_buffer) - 1u; } diff --git a/App/tcp_client.c b/App/tcp_client.c index 8adfe2a..24085de 100644 --- a/App/tcp_client.c +++ b/App/tcp_client.c @@ -48,6 +48,7 @@ static err_t tcp_client_worker(struct netconn *conn, uint8_t link_index) uint8_t src_endpoint = config_link_index_to_endpoint(link_index); err_t err; route_msg_t *tx_msg; + route_send_result_t route_result; netconn_set_recvtimeout(conn, 10); @@ -58,13 +59,21 @@ static err_t tcp_client_worker(struct netconn *conn, uint8_t link_index) void *data; uint16_t len; netbuf_data(buf, &data, &len); - (void)route_send(xTcpRxQueue, - src_endpoint, - uart_endpoint, - (link_index == CONFIG_LINK_C1) ? ROUTE_CONN_C1 : ROUTE_CONN_C2, - (const uint8_t *)data, - len, - pdMS_TO_TICKS(10)); + route_result = route_send(xTcpRxQueue, + src_endpoint, + uart_endpoint, + (link_index == CONFIG_LINK_C1) ? ROUTE_CONN_C1 : ROUTE_CONN_C2, + (const uint8_t *)data, + len, + pdMS_TO_TICKS(10)); + if (route_result != ROUTE_SEND_OK) { + debug_log_printf("[CLI] idx=%u rx-route-fail rc=%s len=%u\r\n", + (unsigned int)link_index, + route_send_result_to_str(route_result), + (unsigned int)len); + netbuf_delete(buf); + return ERR_CLSD; + } } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } else if (err != ERR_TIMEOUT) { diff --git a/App/tcp_server.c b/App/tcp_server.c index 0c3d4a3..9a09340 100644 --- a/App/tcp_server.c +++ b/App/tcp_server.c @@ -11,7 +11,7 @@ #include "debug_log.h" #include "route_msg.h" -static void tcp_server_worker(struct netconn *conn, uint8_t link_index) +static err_t tcp_server_worker(struct netconn *conn, uint8_t link_index) { struct netbuf *buf; const device_config_t *cfg = config_get(); @@ -19,6 +19,7 @@ static void tcp_server_worker(struct netconn *conn, uint8_t link_index) uint8_t src_endpoint = config_link_index_to_endpoint(link_index); err_t err; route_msg_t *tx_msg; + route_send_result_t route_result; netconn_set_recvtimeout(conn, 10); @@ -29,13 +30,21 @@ static void tcp_server_worker(struct netconn *conn, uint8_t link_index) void *data; uint16_t len; netbuf_data(buf, &data, &len); - (void)route_send(xTcpRxQueue, - src_endpoint, - uart_endpoint, - (link_index == CONFIG_LINK_S1) ? ROUTE_CONN_S1 : ROUTE_CONN_S2, - (const uint8_t *)data, - len, - pdMS_TO_TICKS(10)); + route_result = route_send(xTcpRxQueue, + src_endpoint, + uart_endpoint, + (link_index == CONFIG_LINK_S1) ? ROUTE_CONN_S1 : ROUTE_CONN_S2, + (const uint8_t *)data, + len, + pdMS_TO_TICKS(10)); + if (route_result != ROUTE_SEND_OK) { + debug_log_printf("[SRV] idx=%u rx-route-fail rc=%s len=%u\r\n", + (unsigned int)link_index, + route_send_result_to_str(route_result), + (unsigned int)len); + netbuf_delete(buf); + return ERR_CLSD; + } } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } else if (err != ERR_TIMEOUT) { @@ -46,10 +55,12 @@ static void tcp_server_worker(struct netconn *conn, uint8_t link_index) err = netconn_write(conn, tx_msg->data, tx_msg->len, NETCONN_COPY); route_msg_free(tx_msg); if (err != ERR_OK) { - return; + return err; } } } + + return err; } static void tcp_server_task(uint8_t link_index)