From a690789dcf5fb698cd8d85c306ec9f740fa63d52 Mon Sep 17 00:00:00 2001 From: wanckl Date: Fri, 15 Aug 2025 16:28:59 +0800 Subject: [PATCH] fix(driver_twai): update example using wait_tx_done api --- .../twai/twai_error_recovery/README.md | 10 +-- .../main/twai_recovery_main.c | 2 +- .../twai_sender/main/twai_sender.c | 20 +---- .../twai/twai_utils/main/cmd_twai_send.c | 84 ++----------------- 4 files changed, 18 insertions(+), 98 deletions(-) diff --git a/examples/peripherals/twai/twai_error_recovery/README.md b/examples/peripherals/twai/twai_error_recovery/README.md index c3f0b547b8..672f6dfffd 100644 --- a/examples/peripherals/twai/twai_error_recovery/README.md +++ b/examples/peripherals/twai/twai_error_recovery/README.md @@ -45,17 +45,17 @@ idf.py -p PORT flash monitor install twai success node started -sending frame 0 -sending frame 1 +sending frame 0, please trigger error during sending +sending frame 1, please trigger error during sending ... -sending frame 4 +sending frame 4, please trigger error during sending // Manually trigger error here (disconnect TX/RX or short H/L) bus error: 0x2 state changed: error_active -> error_warning ... -sending frame 9 +sending frame 9, please trigger error during sending // Trigger error again bus error: 0x2 state changed: error_passive -> bus_off @@ -66,7 +66,7 @@ waiting ... 0 state changed: bus_off -> error_active node recovered! continue -sending frame 0 +sending frame 0, please trigger error during sending ``` ## Troubleshooting diff --git a/examples/peripherals/twai/twai_error_recovery/main/twai_recovery_main.c b/examples/peripherals/twai/twai_error_recovery/main/twai_recovery_main.c index 88ece2aa76..8e0bf10713 100644 --- a/examples/peripherals/twai/twai_error_recovery/main/twai_recovery_main.c +++ b/examples/peripherals/twai/twai_error_recovery/main/twai_recovery_main.c @@ -89,7 +89,7 @@ void app_main(void) } } } else { - ESP_LOGI(TAG, "sending frame %d", i); + ESP_LOGI(TAG, "sending frame %d, please trigger error during sending", i); tx_frame.header.id = i; ESP_ERROR_CHECK(twai_node_transmit(node_hdl, &tx_frame, 500)); } diff --git a/examples/peripherals/twai/twai_network/twai_sender/main/twai_sender.c b/examples/peripherals/twai/twai_network/twai_sender/main/twai_sender.c index 794cd21ff1..2c9c037c7c 100644 --- a/examples/peripherals/twai/twai_network/twai_sender/main/twai_sender.c +++ b/examples/peripherals/twai/twai_network/twai_sender/main/twai_sender.c @@ -34,13 +34,10 @@ typedef struct { // Transmission completion callback static IRAM_ATTR bool twai_sender_tx_done_callback(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx) { - BaseType_t woken; - SemaphoreHandle_t *tx_semaphore = (SemaphoreHandle_t *)user_ctx; if (!edata->is_tx_success) { ESP_EARLY_LOGW(TAG, "Failed to transmit message, ID: 0x%X", edata->done_tx_frame->header.id); } - xSemaphoreGiveFromISR(*tx_semaphore, &woken); - return (woken == pdTRUE); + return false; // No task wake required } // Bus error callback @@ -53,7 +50,6 @@ static IRAM_ATTR bool twai_sender_on_error_callback(twai_node_handle_t handle, c void app_main(void) { twai_node_handle_t sender_node = NULL; - SemaphoreHandle_t tx_semaphore = NULL; printf("===================TWAI Sender Example Starting...===================\n"); // Configure TWAI node @@ -79,15 +75,10 @@ void app_main(void) .on_tx_done = twai_sender_tx_done_callback, .on_error = twai_sender_on_error_callback, }; - ESP_ERROR_CHECK(twai_node_register_event_callbacks(sender_node, &callbacks, &tx_semaphore)); + ESP_ERROR_CHECK(twai_node_register_event_callbacks(sender_node, &callbacks, NULL)); // Enable TWAI node ESP_ERROR_CHECK(twai_node_enable(sender_node)); - - // Create semaphore for transmission completion - tx_semaphore = xSemaphoreCreateCounting(howmany(TWAI_DATA_LEN, TWAI_FRAME_MAX_LEN), 0); - assert(tx_semaphore != NULL); - ESP_LOGI(TAG, "TWAI Sender started successfully"); ESP_LOGI(TAG, "Sending messages with IDs: 0x%03X (data), 0x%03X (heartbeat)", TWAI_DATA_ID, TWAI_HEARTBEAT_ID); @@ -101,7 +92,7 @@ void app_main(void) }; ESP_ERROR_CHECK(twai_node_transmit(sender_node, &tx_frame, 500)); ESP_LOGI(TAG, "Sending heartbeat message: %lld", timestamp); - xSemaphoreTake(tx_semaphore, portMAX_DELAY); + ESP_ERROR_CHECK(twai_node_transmit_wait_all_done(sender_node, -1)); // -1 means wait forever // Send burst data messages every 10 seconds if ((timestamp / 1000000) % 10 == 0) { @@ -118,9 +109,7 @@ void app_main(void) } // Frames mounted, wait for all frames to be transmitted - for (int i = 0; i < num_frames; i++) { - xSemaphoreTake(tx_semaphore, portMAX_DELAY); - } + ESP_ERROR_CHECK(twai_node_transmit_wait_all_done(sender_node, -1)); free(data); } @@ -133,7 +122,6 @@ void app_main(void) } } - vSemaphoreDelete(tx_semaphore); ESP_ERROR_CHECK(twai_node_disable(sender_node)); ESP_ERROR_CHECK(twai_node_delete(sender_node)); } diff --git a/examples/peripherals/twai/twai_utils/main/cmd_twai_send.c b/examples/peripherals/twai/twai_utils/main/cmd_twai_send.c index e222e3f2b4..6fd138d4ac 100644 --- a/examples/peripherals/twai/twai_utils/main/cmd_twai_send.c +++ b/examples/peripherals/twai/twai_utils/main/cmd_twai_send.c @@ -42,66 +42,13 @@ static struct { static bool twai_send_tx_done_cb(twai_node_handle_t handle, const twai_tx_done_event_data_t *event_data, void *user_ctx) { ESP_UNUSED(handle); - ESP_UNUSED(event_data); twai_controller_ctx_t *controller = (twai_controller_ctx_t *)user_ctx; - - /* Signal TX completion */ - if (atomic_load(&controller->send_ctx.is_tx_pending)) { - atomic_store(&controller->send_ctx.is_tx_pending, false); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xSemaphoreGiveFromISR(controller->send_ctx.tx_done_sem, &xHigherPriorityTaskWoken); - return xHigherPriorityTaskWoken == pdTRUE; - } - - return false; -} - -/** - * @brief Initialize the send module for a controller - * - * @param[in] controller Pointer to the controller context - * - * @return @c ESP_OK on success, error code on failure - */ -static esp_err_t twai_send_init_controller(twai_controller_ctx_t *controller) -{ int controller_id = controller - &g_twai_controller_ctx[0]; - /* Create TX completion semaphore */ - controller->send_ctx.tx_done_sem = xSemaphoreCreateBinary(); - if (controller->send_ctx.tx_done_sem == NULL) { - ESP_LOGE(TAG, "Failed to create TX semaphore for controller %d", controller_id); - return ESP_ERR_NO_MEM; + if (!event_data->is_tx_success) { + ESP_EARLY_LOGW(TAG, "Node %d: Bus error when sending frame with ID: 0x%X", controller_id, event_data->done_tx_frame->header.id); } - - /* Initialize TX pending flag */ - atomic_init(&controller->send_ctx.is_tx_pending, false); - - /* Register TX done callback */ - twai_core_ctx_t *core_ctx = &controller->core_ctx; - core_ctx->driver_cbs.on_tx_done = twai_send_tx_done_cb; - - return ESP_OK; -} - -/** - * @brief Deinitialize the send module for a controller - * - * @param[in] controller Pointer to the controller context - */ -static void twai_send_deinit_controller(twai_controller_ctx_t *controller) -{ - /* Clear pending flag */ - atomic_store(&controller->send_ctx.is_tx_pending, false); - - /* Delete TX completion semaphore */ - if (controller->send_ctx.tx_done_sem) { - vSemaphoreDelete(controller->send_ctx.tx_done_sem); - controller->send_ctx.tx_done_sem = NULL; - } - - /* Clear callback */ - controller->core_ctx.driver_cbs.on_tx_done = NULL; + return false; } /** @@ -115,33 +62,21 @@ static void twai_send_deinit_controller(twai_controller_ctx_t *controller) */ static esp_err_t send_frame_sync(twai_controller_ctx_t *controller, const twai_frame_t *frame, uint32_t timeout_ms) { - if (!controller) { - ESP_LOGE(TAG, "Invalid controller pointer"); - return ESP_ERR_INVALID_ARG; - } + ESP_RETURN_ON_FALSE(controller, ESP_ERR_INVALID_ARG, TAG, "Invalid controller pointer"); int controller_id = controller - &g_twai_controller_ctx[0]; - esp_err_t ret = ESP_OK; twai_core_ctx_t *ctx = &controller->core_ctx; /* Check if TWAI driver is running */ ESP_RETURN_ON_FALSE(atomic_load(&ctx->is_initialized), ESP_ERR_INVALID_STATE, TAG, "TWAI%d not initialized", controller_id); - /* Mark TX as pending */ - atomic_store(&controller->send_ctx.is_tx_pending, true); - /* Transmit the frame */ - ret = twai_node_transmit(controller->node_handle, frame, timeout_ms); - ESP_GOTO_ON_ERROR(ret, err, TAG, "Node %d: Failed to queue TX frame: %s", controller_id, esp_err_to_name(ret)); + ESP_RETURN_ON_ERROR(twai_node_transmit(controller->node_handle, frame, timeout_ms), TAG, "Node %d: Failed to queue TX frame", controller_id); /* Wait for TX completion or timeout */ - ESP_GOTO_ON_FALSE(xSemaphoreTake(controller->send_ctx.tx_done_sem, pdMS_TO_TICKS(timeout_ms)) == pdTRUE, ESP_ERR_TIMEOUT, err, TAG, - "Node %d: TX timed out after %"PRIu32" ms", controller_id, timeout_ms); + ESP_RETURN_ON_ERROR(twai_node_transmit_wait_all_done(controller->node_handle, timeout_ms), TAG, "Node %d: TX not completed after %"PRIu32" ms", controller_id, timeout_ms); return ESP_OK; -err: - atomic_store(&controller->send_ctx.is_tx_pending, false); - return ret; } /** @@ -228,10 +163,7 @@ void register_twai_send_commands(void) /* Initialize send context for all controllers */ for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) { twai_controller_ctx_t *controller = &g_twai_controller_ctx[i]; - esp_err_t ret = twai_send_init_controller(controller); - if (ret != ESP_OK) { - ESP_LOGW(TAG, "Failed to initialize send module for TWAI%d: %s", i, esp_err_to_name(ret)); - } + controller->core_ctx.driver_cbs.on_tx_done = twai_send_tx_done_cb; } /* Register command arguments */ @@ -270,6 +202,6 @@ void unregister_twai_send_commands(void) /* Cleanup all controller send modules */ for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) { twai_controller_ctx_t *controller = &g_twai_controller_ctx[i]; - twai_send_deinit_controller(controller); + controller->core_ctx.driver_cbs.on_tx_done = NULL; } }