From ae5f8e550c6827c58101fbc07ffbf9c785052782 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 23 Apr 2025 15:37:54 +0800 Subject: [PATCH] feat(rmt): introduce RMT_ENCODER_FUNC_ATTR for encoder functions Closes https://github.com/espressif/esp-idf/issues/15832 --- components/esp_driver_rmt/Kconfig | 18 +++++++------ .../include/driver/rmt_encoder.h | 8 ++++++ components/esp_driver_rmt/linker.lf | 12 ++------- .../esp_driver_rmt/src/rmt_encoder_bs.c | 25 ++++++++++++------- .../esp_driver_rmt/src/rmt_encoder_bytes.c | 2 ++ .../esp_driver_rmt/src/rmt_encoder_copy.c | 2 ++ .../esp_driver_rmt/src/rmt_encoder_simple.c | 2 ++ components/esp_driver_rmt/src/rmt_rx.c | 8 +++++- components/esp_driver_rmt/src/rmt_tx.c | 8 +++++- .../rmt/main/test_rmt_bitscrambler.c | 7 ++++++ .../rmt/main/test_util_rmt_encoders.c | 12 ++++++--- .../test_apps/rmt/sdkconfig.ci.cache_safe | 3 +++ docs/en/api-reference/peripherals/rmt.rst | 2 ++ docs/zh_CN/api-reference/peripherals/rmt.rst | 2 ++ .../rmt/dshot_esc/main/dshot_esc_encoder.c | 2 ++ .../ir_nec_transceiver/main/ir_nec_encoder.c | 2 ++ .../rmt/led_strip/main/led_strip_encoder.c | 2 ++ .../main/musical_score_encoder.c | 2 ++ .../main/stepper_motor_encoder.c | 2 ++ 19 files changed, 88 insertions(+), 33 deletions(-) diff --git a/components/esp_driver_rmt/Kconfig b/components/esp_driver_rmt/Kconfig index e0a522f4d9..601c908968 100644 --- a/components/esp_driver_rmt/Kconfig +++ b/components/esp_driver_rmt/Kconfig @@ -1,12 +1,16 @@ menu "ESP-Driver:RMT Configurations" depends on SOC_RMT_SUPPORTED + config RMT_ENCODER_FUNC_IN_IRAM + bool "Place RMT encoder function in IRAM" + default y + help + Place RMT encoder function into IRAM for better performance and fewer cache misses. + config RMT_TX_ISR_HANDLER_IN_IRAM bool "Place RMT TX ISR handler in IRAM to reduce latency" default y select RMT_OBJ_CACHE_SAFE - select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA - select BITSCRAMBLER_CTRL_FUNC_IN_IRAM if SOC_BITSCRAMBLER_SUPPORTED && SOC_RMT_SUPPORT_DMA help Place RMT TX ISR handler in IRAM to reduce latency caused by cache miss. @@ -21,14 +25,13 @@ menu "ESP-Driver:RMT Configurations" bool "Place RMT receive function in IRAM" default n select RMT_OBJ_CACHE_SAFE - select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA help Place RMT receive function into IRAM for better performance and fewer cache misses. config RMT_TX_ISR_CACHE_SAFE - bool "Allow RMT TX ISR to execute when cache is disabled" + bool "Allow RMT TX ISR to execute when cache is disabled" if !SPI_FLASH_AUTO_SUSPEND select RMT_TX_ISR_HANDLER_IN_IRAM - select GDMA_ISR_HANDLER_IN_IRAM if SOC_RMT_SUPPORT_DMA + select RMT_ENCODER_FUNC_IN_IRAM default n help Enable this option to allow the RMT TX Interrupt Service Routine (ISR) @@ -36,9 +39,8 @@ menu "ESP-Driver:RMT Configurations" might be turned off, but the RMT TX functionality is still required to operate correctly. config RMT_RX_ISR_CACHE_SAFE - bool "Allow RMT RX ISR to execute when cache is disabled" + bool "Allow RMT RX ISR to execute when cache is disabled" if !SPI_FLASH_AUTO_SUSPEND select RMT_RX_ISR_HANDLER_IN_IRAM - select GDMA_ISR_HANDLER_IN_IRAM if SOC_RMT_SUPPORT_DMA default n help Enable this option to allow the RMT RX Interrupt Service Routine (ISR) @@ -63,7 +65,7 @@ menu "ESP-Driver:RMT Configurations" Please enable this option by caution, as it will increase the binary size. config RMT_ISR_IRAM_SAFE - bool "RMT ISR IRAM-Safe (Deprecated)" + bool "RMT ISR IRAM-Safe (Deprecated)" if !SPI_FLASH_AUTO_SUSPEND select RMT_TX_ISR_CACHE_SAFE select RMT_RX_ISR_CACHE_SAFE default n diff --git a/components/esp_driver_rmt/include/driver/rmt_encoder.h b/components/esp_driver_rmt/include/driver/rmt_encoder.h index 0113f7fc54..0ed5255e81 100644 --- a/components/esp_driver_rmt/include/driver/rmt_encoder.h +++ b/components/esp_driver_rmt/include/driver/rmt_encoder.h @@ -7,7 +7,9 @@ #pragma once #include +#include "sdkconfig.h" #include "esp_err.h" +#include "esp_attr.h" #include "hal/rmt_types.h" #include "driver/rmt_types.h" @@ -69,6 +71,12 @@ struct rmt_encoder_t { esp_err_t (*del)(rmt_encoder_t *encoder); }; +#if CONFIG_RMT_ENCODER_FUNC_IN_IRAM +#define RMT_ENCODER_FUNC_ATTR IRAM_ATTR +#else +#define RMT_ENCODER_FUNC_ATTR +#endif + /** * @brief Callback for simple callback encoder * diff --git a/components/esp_driver_rmt/linker.lf b/components/esp_driver_rmt/linker.lf index f94852a40a..b8f780bf18 100644 --- a/components/esp_driver_rmt/linker.lf +++ b/components/esp_driver_rmt/linker.lf @@ -8,13 +8,6 @@ entries: rmt_tx: rmt_tx_do_transaction (noflash) rmt_tx: rmt_encode_check_result (noflash) rmt_tx: rmt_tx_mark_eof (noflash) - rmt_encoder: rmt_encoder_reset (noflash) - rmt_encoder_bytes: rmt_encode_bytes (noflash) - rmt_encoder_bytes: rmt_bytes_encoder_reset (noflash) - rmt_encoder_copy: rmt_encode_copy (noflash) - rmt_encoder_copy: rmt_copy_encoder_reset (noflash) - rmt_encoder_simple: rmt_encode_simple (noflash) - rmt_encoder_simple: rmt_simple_encoder_reset (noflash) if SOC_RMT_SUPPORT_TX_LOOP_COUNT = y: rmt_tx: rmt_isr_handle_tx_loop_end (noflash) @@ -22,9 +15,8 @@ entries: if SOC_RMT_SUPPORT_DMA = y: rmt_tx: rmt_dma_tx_eof_cb (noflash) - if SOC_BITSCRAMBLER_SUPPORTED = y: - rmt_encoder_bs: rmt_encode_bs (noflash) - rmt_encoder_bs: rmt_bs_encoder_reset (noflash) + if RMT_ENCODER_FUNC_IN_IRAM = y: + rmt_encoder: rmt_encoder_reset (noflash) if RMT_RX_ISR_HANDLER_IN_IRAM = y: rmt_rx: rmt_rx_default_isr (noflash) diff --git a/components/esp_driver_rmt/src/rmt_encoder_bs.c b/components/esp_driver_rmt/src/rmt_encoder_bs.c index cc6331f171..e77842a5b7 100644 --- a/components/esp_driver_rmt/src/rmt_encoder_bs.c +++ b/components/esp_driver_rmt/src/rmt_encoder_bs.c @@ -14,6 +14,7 @@ typedef struct rmt_bs_encoder_t { bitscrambler_handle_t bs; // BitScrambler handle } rmt_bs_encoder_t; +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_bs_encoder_reset(rmt_encoder_t *encoder) { rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base); @@ -23,14 +24,7 @@ static esp_err_t rmt_bs_encoder_reset(rmt_encoder_t *encoder) return ESP_OK; } -static esp_err_t rmt_del_bs_encoder(rmt_encoder_t *encoder) -{ - rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base); - bitscrambler_free(bs_encoder->bs); - free(bs_encoder); - return ESP_OK; -} - +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *input_raw, size_t data_size, rmt_encode_state_t *ret_state) { @@ -109,11 +103,24 @@ static size_t rmt_encode_bs(rmt_encoder_t *encoder, rmt_channel_handle_t channel return copy_len; } +static esp_err_t rmt_del_bs_encoder(rmt_encoder_t *encoder) +{ + rmt_bs_encoder_t *bs_encoder = __containerof(encoder, rmt_bs_encoder_t, base); + bitscrambler_free(bs_encoder->bs); + free(bs_encoder); + return ESP_OK; +} + esp_err_t rmt_new_bitscrambler_encoder(const rmt_bs_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) { esp_err_t ret = ESP_OK; rmt_bs_encoder_t *encoder = NULL; - ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + // bitscrambler function is used under RMT TX ISR context + // if the cache is disabled, all functions called by ISR must be in IRAM +#if CONFIG_RMT_TX_ISR_CACHE_SAFE && !CONFIG_BITSCRAMBLER_CTRL_FUNC_IN_IRAM + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_BITSCRAMBLER_CTRL_FUNC_IN_IRAM must be enabled"); +#endif encoder = rmt_alloc_encoder_mem(sizeof(rmt_bs_encoder_t)); ESP_GOTO_ON_FALSE(encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for bitscrambler encoder"); diff --git a/components/esp_driver_rmt/src/rmt_encoder_bytes.c b/components/esp_driver_rmt/src/rmt_encoder_bytes.c index 5bf5e9acb3..cd04a3c9f1 100644 --- a/components/esp_driver_rmt/src/rmt_encoder_bytes.c +++ b/components/esp_driver_rmt/src/rmt_encoder_bytes.c @@ -18,6 +18,7 @@ typedef struct rmt_bytes_encoder_t { } flags; } rmt_bytes_encoder_t; +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_bytes_encoder_reset(rmt_encoder_t *encoder) { rmt_bytes_encoder_t *bytes_encoder = __containerof(encoder, rmt_bytes_encoder_t, base); @@ -27,6 +28,7 @@ static esp_err_t rmt_bytes_encoder_reset(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_bytes(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { diff --git a/components/esp_driver_rmt/src/rmt_encoder_copy.c b/components/esp_driver_rmt/src/rmt_encoder_copy.c index 8a9a2977c1..a28abbb303 100644 --- a/components/esp_driver_rmt/src/rmt_encoder_copy.c +++ b/components/esp_driver_rmt/src/rmt_encoder_copy.c @@ -12,6 +12,7 @@ typedef struct rmt_copy_encoder_t { size_t last_symbol_index; // index of symbol position in the primary stream } rmt_copy_encoder_t; +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_copy_encoder_reset(rmt_encoder_t *encoder) { rmt_copy_encoder_t *copy_encoder = __containerof(encoder, rmt_copy_encoder_t, base); @@ -19,6 +20,7 @@ static esp_err_t rmt_copy_encoder_reset(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_copy(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *input_symbols, size_t data_size, rmt_encode_state_t *ret_state) { diff --git a/components/esp_driver_rmt/src/rmt_encoder_simple.c b/components/esp_driver_rmt/src/rmt_encoder_simple.c index 2a530739a0..5f3284b24b 100644 --- a/components/esp_driver_rmt/src/rmt_encoder_simple.c +++ b/components/esp_driver_rmt/src/rmt_encoder_simple.c @@ -19,6 +19,7 @@ typedef struct rmt_simple_encoder_t { bool callback_done; //true if we can't call the callback for more data anymore. } rmt_simple_encoder_t; +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_simple_encoder_reset(rmt_encoder_t *encoder) { rmt_simple_encoder_t *simple_encoder = __containerof(encoder, rmt_simple_encoder_t, base); @@ -29,6 +30,7 @@ static esp_err_t rmt_simple_encoder_reset(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_simple(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *data, size_t data_size, rmt_encode_state_t *ret_state) { diff --git a/components/esp_driver_rmt/src/rmt_rx.c b/components/esp_driver_rmt/src/rmt_rx.c index 3875b47c89..610df25ba7 100644 --- a/components/esp_driver_rmt/src/rmt_rx.c +++ b/components/esp_driver_rmt/src/rmt_rx.c @@ -180,7 +180,13 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, TAG, "invalid GPIO number %d", config->gpio_num); ESP_RETURN_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL, ESP_ERR_INVALID_ARG, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL); -#if !SOC_RMT_SUPPORT_DMA +#if SOC_RMT_SUPPORT_DMA + if (config->flags.with_dma) { +#if CONFIG_RMT_RX_ISR_CACHE_SAFE && (!CONFIG_GDMA_ISR_HANDLER_IN_IRAM || !CONFIG_GDMA_CTRL_FUNC_IN_IRAM) + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_GDMA_ISR_HANDLER_IN_IRAM and CONFIG_GDMA_CTRL_FUNC_IN_IRAM must be enabled"); +#endif + } +#else ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported"); #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/esp_driver_rmt/src/rmt_tx.c b/components/esp_driver_rmt/src/rmt_tx.c index 979641dee4..79bd447cda 100644 --- a/components/esp_driver_rmt/src/rmt_tx.c +++ b/components/esp_driver_rmt/src/rmt_tx.c @@ -243,7 +243,13 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, TAG, "invalid GPIO number %d", config->gpio_num); ESP_RETURN_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL, ESP_ERR_INVALID_ARG, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL); -#if !SOC_RMT_SUPPORT_DMA +#if SOC_RMT_SUPPORT_DMA + if (config->flags.with_dma) { +#if CONFIG_RMT_TX_ISR_CACHE_SAFE && (!CONFIG_GDMA_ISR_HANDLER_IN_IRAM || !CONFIG_GDMA_CTRL_FUNC_IN_IRAM) + ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "CONFIG_GDMA_ISR_HANDLER_IN_IRAM and CONFIG_GDMA_CTRL_FUNC_IN_IRAM must be enabled"); +#endif + } +#else ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported"); #endif diff --git a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_bitscrambler.c b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_bitscrambler.c index 4879b07999..8ee05f5ee5 100644 --- a/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_bitscrambler.c +++ b/components/esp_driver_rmt/test_apps/rmt/main/test_rmt_bitscrambler.c @@ -97,6 +97,13 @@ TEST_CASE("rmt TX with bitscrambler", "[rmt]") }, 5, &transmit_config)); TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000))); + TEST_ESP_OK(rmt_receive(rx_channel, symbols, sizeof(symbols), &receive_config)); + printf("transmit again!\r\n"); + TEST_ESP_OK(rmt_transmit(tx_channel, bs_encoder, (uint8_t[]) { + 0x12, 0x34, 0x56, 0x78, 0x9a, // dummy test values, will be further processed by bitscrambler program + }, 5, &transmit_config)); + TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000))); + printf("disable tx+rx channel\r\n"); TEST_ESP_OK(rmt_disable(tx_channel)); TEST_ESP_OK(rmt_disable(rx_channel)); diff --git a/components/esp_driver_rmt/test_apps/rmt/main/test_util_rmt_encoders.c b/components/esp_driver_rmt/test_apps/rmt/main/test_util_rmt_encoders.c index 1ca22be6c5..9917c6a0f8 100644 --- a/components/esp_driver_rmt/test_apps/rmt/main/test_util_rmt_encoders.c +++ b/components/esp_driver_rmt/test_apps/rmt/main/test_util_rmt_encoders.c @@ -20,7 +20,8 @@ typedef struct { rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; -IRAM_ATTR static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +RMT_ENCODER_FUNC_ATTR +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_encode_state_t session_state = RMT_ENCODING_RESET; @@ -62,7 +63,8 @@ static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) return ESP_OK; } -IRAM_ATTR static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +RMT_ENCODER_FUNC_ATTR +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); rmt_encoder_reset(led_encoder->bytes_encoder); @@ -113,7 +115,8 @@ typedef struct { int state; } rmt_nec_protocol_encoder_t; -IRAM_ATTR static size_t rmt_encode_nec_protocol(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +RMT_ENCODER_FUNC_ATTR +static size_t rmt_encode_nec_protocol(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_nec_protocol_encoder_t *nec_encoder = __containerof(encoder, rmt_nec_protocol_encoder_t, base); rmt_encode_state_t session_state = RMT_ENCODING_RESET; @@ -177,7 +180,8 @@ static esp_err_t rmt_del_nec_protocol_encoder(rmt_encoder_t *encoder) return ESP_OK; } -IRAM_ATTR static esp_err_t rmt_nec_protocol_encoder_reset(rmt_encoder_t *encoder) +RMT_ENCODER_FUNC_ATTR +static esp_err_t rmt_nec_protocol_encoder_reset(rmt_encoder_t *encoder) { rmt_nec_protocol_encoder_t *nec_encoder = __containerof(encoder, rmt_nec_protocol_encoder_t, base); rmt_encoder_reset(nec_encoder->copy_encoder); diff --git a/components/esp_driver_rmt/test_apps/rmt/sdkconfig.ci.cache_safe b/components/esp_driver_rmt/test_apps/rmt/sdkconfig.ci.cache_safe index d45928d247..9a539ffdda 100644 --- a/components/esp_driver_rmt/test_apps/rmt/sdkconfig.ci.cache_safe +++ b/components/esp_driver_rmt/test_apps/rmt/sdkconfig.ci.cache_safe @@ -3,6 +3,9 @@ CONFIG_RMT_TX_ISR_CACHE_SAFE=y CONFIG_RMT_RX_ISR_CACHE_SAFE=y CONFIG_RMT_RECV_FUNC_IN_IRAM=y CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y +CONFIG_BITSCRAMBLER_CTRL_FUNC_IN_IRAM=y +CONFIG_GDMA_ISR_HANDLER_IN_IRAM=y +CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y CONFIG_COMPILER_OPTIMIZATION_NONE=y # place non-ISR FreeRTOS functions in Flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y diff --git a/docs/en/api-reference/peripherals/rmt.rst b/docs/en/api-reference/peripherals/rmt.rst index 767538680a..41fa81aa11 100644 --- a/docs/en/api-reference/peripherals/rmt.rst +++ b/docs/en/api-reference/peripherals/rmt.rst @@ -589,6 +589,8 @@ There is a Kconfig option :ref:`CONFIG_RMT_TX_ISR_CACHE_SAFE` and :ref:`CONFIG_R This Kconfig option allows the interrupt handler to run while the cache is disabled but comes at the cost of increased IRAM consumption. +Please note, when :ref:`CONFIG_RMT_TX_ISR_CACHE_SAFE` is enabled, you must also place the encoder functions (mainly the :cpp:member:`rmt_encoder_t::encode` and :cpp:member:`rmt_encoder_t::reset`) into IRAM. You can use :c:macro:`RMT_ENCODER_FUNC_ATTR` to decorate your encoder functions. + Another Kconfig option :ref:`CONFIG_RMT_RECV_FUNC_IN_IRAM` can place :cpp:func:`rmt_receive` into the IRAM as well. So that the receive function can be used even when the flash cache is disabled. .. _rmt-thread-safety: diff --git a/docs/zh_CN/api-reference/peripherals/rmt.rst b/docs/zh_CN/api-reference/peripherals/rmt.rst index 85d13621c2..9d633f8fd6 100644 --- a/docs/zh_CN/api-reference/peripherals/rmt.rst +++ b/docs/zh_CN/api-reference/peripherals/rmt.rst @@ -589,6 +589,8 @@ Cache 安全 启用该选项可以保证 cache 禁用时的中断运行,但会相应增加 IRAM 占用。 +请注意,当 :ref:`CONFIG_RMT_TX_ISR_CACHE_SAFE` 使能后,你必须将编码器函数 (主要是 :cpp:member:`rmt_encoder_t::encode` 和 :cpp:member:`rmt_encoder_t::reset`) 放进 IRAM 中。建议你使用 :c:macro:`RMT_ENCODER_FUNC_ATTR` 来装饰你的编码器函数。 + 另外一个 Kconfig 选项 :ref:`CONFIG_RMT_RECV_FUNC_IN_IRAM` 可以将 :cpp:func:`rmt_receive` 函数放进内部的 IRAM 中,从而当 flash cache 被关闭的时候,这个函数也能够被使用。 .. _rmt-thread-safety: diff --git a/examples/peripherals/rmt/dshot_esc/main/dshot_esc_encoder.c b/examples/peripherals/rmt/dshot_esc/main/dshot_esc_encoder.c index 0ba5c7090b..e8f300b6b2 100644 --- a/examples/peripherals/rmt/dshot_esc/main/dshot_esc_encoder.c +++ b/examples/peripherals/rmt/dshot_esc/main/dshot_esc_encoder.c @@ -45,6 +45,7 @@ static void make_dshot_frame(dshot_esc_frame_t *frame, uint16_t throttle, bool t frame->val = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8); } +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_dshot_esc(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { @@ -97,6 +98,7 @@ static esp_err_t rmt_del_dshot_encoder(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_dshot_encoder_reset(rmt_encoder_t *encoder) { rmt_dshot_esc_encoder_t *dshot_encoder = __containerof(encoder, rmt_dshot_esc_encoder_t, base); diff --git a/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_encoder.c b/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_encoder.c index 74c403568a..de4a5d654b 100644 --- a/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_encoder.c +++ b/examples/peripherals/rmt/ir_nec_transceiver/main/ir_nec_encoder.c @@ -18,6 +18,7 @@ typedef struct { int state; } rmt_ir_nec_encoder_t; +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_ir_nec(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base); @@ -85,6 +86,7 @@ static esp_err_t rmt_del_ir_nec_encoder(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_ir_nec_encoder_reset(rmt_encoder_t *encoder) { rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base); diff --git a/examples/peripherals/rmt/led_strip/main/led_strip_encoder.c b/examples/peripherals/rmt/led_strip/main/led_strip_encoder.c index de8638cfab..243c4273ed 100644 --- a/examples/peripherals/rmt/led_strip/main/led_strip_encoder.c +++ b/examples/peripherals/rmt/led_strip/main/led_strip_encoder.c @@ -17,6 +17,7 @@ typedef struct { rmt_symbol_word_t reset_code; } rmt_led_strip_encoder_t; +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); @@ -62,6 +63,7 @@ static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) { rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); diff --git a/examples/peripherals/rmt/musical_buzzer/main/musical_score_encoder.c b/examples/peripherals/rmt/musical_buzzer/main/musical_score_encoder.c index 26035bec02..c94fa721f2 100644 --- a/examples/peripherals/rmt/musical_buzzer/main/musical_score_encoder.c +++ b/examples/peripherals/rmt/musical_buzzer/main/musical_score_encoder.c @@ -15,6 +15,7 @@ typedef struct { uint32_t resolution; } rmt_musical_score_encoder_t; +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_musical_score(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_musical_score_encoder_t *score_encoder = __containerof(encoder, rmt_musical_score_encoder_t, base); @@ -41,6 +42,7 @@ static esp_err_t rmt_del_musical_score_encoder(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_musical_score_encoder_reset(rmt_encoder_t *encoder) { rmt_musical_score_encoder_t *score_encoder = __containerof(encoder, rmt_musical_score_encoder_t, base); diff --git a/examples/peripherals/rmt/stepper_motor/main/stepper_motor_encoder.c b/examples/peripherals/rmt/stepper_motor/main/stepper_motor_encoder.c index e30429b321..a141babf8c 100644 --- a/examples/peripherals/rmt/stepper_motor/main/stepper_motor_encoder.c +++ b/examples/peripherals/rmt/stepper_motor/main/stepper_motor_encoder.c @@ -27,6 +27,7 @@ typedef struct { rmt_symbol_word_t curve_table[]; } rmt_stepper_curve_encoder_t; +RMT_ENCODER_FUNC_ATTR static size_t rmt_encode_stepper_motor_curve(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) { rmt_stepper_curve_encoder_t *motor_encoder = __containerof(encoder, rmt_stepper_curve_encoder_t, base); @@ -53,6 +54,7 @@ static esp_err_t rmt_del_stepper_motor_curve_encoder(rmt_encoder_t *encoder) return ESP_OK; } +RMT_ENCODER_FUNC_ATTR static esp_err_t rmt_reset_stepper_motor_curve_encoder(rmt_encoder_t *encoder) { rmt_stepper_curve_encoder_t *motor_encoder = __containerof(encoder, rmt_stepper_curve_encoder_t, base);