From 61f19094b029057c8ae961f434f45ff84eed9065 Mon Sep 17 00:00:00 2001 From: wangyuanze Date: Thu, 14 Jul 2022 10:08:29 +0800 Subject: [PATCH] example: fix rmt callback memory issue in ir_nec_transceiver --- components/driver/include/driver/rmt_types.h | 7 ++++--- .../main/ir_nec_transceiver_main.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/components/driver/include/driver/rmt_types.h b/components/driver/include/driver/rmt_types.h index dd05b4cae0..96d1f5d936 100644 --- a/components/driver/include/driver/rmt_types.h +++ b/components/driver/include/driver/rmt_types.h @@ -40,7 +40,8 @@ typedef struct { /** * @brief Prototype of RMT event callback * @param[in] tx_chan RMT channel handle, created from `rmt_new_tx_channel()` - * @param[in] edata RMT event data + * @param[in] edata Point to RMT event data. The lifecycle of this pointer memory is inside this function, + * user should copy it into static memory if used outside this funcion. * @param[in] user_ctx User registered context, passed from `rmt_tx_register_event_callbacks()` * * @return Whether a high priority task has been waken up by this callback function @@ -59,9 +60,9 @@ typedef struct { * @brief Prototype of RMT event callback * * @param[in] rx_chan RMT channel handle, created from `rmt_new_rx_channel()` - * @param[in] edata Point to RMT event data + * @param[in] edata Point to RMT event data. The lifecycle of this pointer memory is inside this function, + * user should copy it into static memory if used outside this funcion. * @param[in] user_ctx User registered context, passed from `rmt_rx_register_event_callbacks()` - * * @return Whether a high priority task has been waken up by this function */ typedef bool (*rmt_rx_done_callback_t)(rmt_channel_handle_t rx_chan, rmt_rx_done_event_data_t *edata, void *user_ctx); diff --git a/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_transceiver_main.c b/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_transceiver_main.c index c07a054b38..b376105d07 100644 --- a/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_transceiver_main.c +++ b/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_transceiver_main.c @@ -6,6 +6,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "esp_log.h" #include "driver/rmt_tx.h" #include "driver/rmt_rx.h" @@ -144,9 +145,9 @@ static void example_parse_nec_frame(rmt_symbol_word_t *rmt_nec_symbols, size_t s static bool example_rmt_rx_done_callback(rmt_channel_handle_t channel, rmt_rx_done_event_data_t *edata, void *user_data) { BaseType_t high_task_wakeup = pdFALSE; - TaskHandle_t task_to_notify = (TaskHandle_t)user_data; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; // send the received RMT symbols to the parser task - xTaskNotifyFromISR(task_to_notify, (uint32_t)edata, eSetValueWithOverwrite, &high_task_wakeup); + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); return high_task_wakeup == pdTRUE; } @@ -163,11 +164,12 @@ void app_main(void) ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_channel_cfg, &rx_channel)); ESP_LOGI(TAG, "register RX done callback"); - TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); + QueueHandle_t receive_queue = xQueueCreate(1, sizeof(rmt_rx_done_event_data_t)); + assert(receive_queue); rmt_rx_event_callbacks_t cbs = { .on_recv_done = example_rmt_rx_done_callback, }; - ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rx_channel, &cbs, cur_task)); + ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rx_channel, &cbs, receive_queue)); // the following timing requirement is based on NEC protocol rmt_receive_config_t receive_config = { @@ -211,14 +213,14 @@ void app_main(void) // save the received RMT symbols rmt_symbol_word_t raw_symbols[64]; // 64 symbols should be sufficient for a standard NEC frame - rmt_rx_done_event_data_t *rx_data = NULL; + rmt_rx_done_event_data_t rx_data; // ready to receive ESP_ERROR_CHECK(rmt_receive(rx_channel, raw_symbols, sizeof(raw_symbols), &receive_config)); while (1) { // wait for RX done signal - if (xTaskNotifyWait(0x00, ULONG_MAX, (uint32_t *)&rx_data, pdMS_TO_TICKS(1000)) == pdTRUE) { + if (xQueueReceive(receive_queue, &rx_data, pdMS_TO_TICKS(1000)) == pdPASS) { // parse the receive symbols and print the result - example_parse_nec_frame(rx_data->received_symbols, rx_data->num_symbols); + example_parse_nec_frame(rx_data.received_symbols, rx_data.num_symbols); // start receive again ESP_ERROR_CHECK(rmt_receive(rx_channel, raw_symbols, sizeof(raw_symbols), &receive_config)); } else {