From 706005c2e61ed361e5833b40c85f85216e6be3df Mon Sep 17 00:00:00 2001 From: zwx Date: Thu, 11 Jan 2024 15:36:44 +0800 Subject: [PATCH] feat(802.15.4): introduce pending tx while rx feature --- .../hal/include/hal/ieee802154_common_ll.h | 9 +++- components/ieee802154/Kconfig | 6 +-- .../ieee802154/driver/esp_ieee802154_debug.c | 17 ++++++- .../ieee802154/driver/esp_ieee802154_dev.c | 47 ++++++++++++++++--- components/ieee802154/linker.lf | 4 ++ .../private_include/esp_ieee802154_util.h | 9 +++- 6 files changed, 79 insertions(+), 13 deletions(-) diff --git a/components/hal/include/hal/ieee802154_common_ll.h b/components/hal/include/hal/ieee802154_common_ll.h index 7520761b77..0cea3682b0 100644 --- a/components/hal/include/hal/ieee802154_common_ll.h +++ b/components/hal/include/hal/ieee802154_common_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -168,6 +168,8 @@ typedef enum { IEEE802154_ED_SAMPLE_AVG = 0x01, } ieee802154_ll_ed_sample_mode_t; +#define IEEE802154_RX_STATUS_RECEIVE_SFD 0x1 + FORCE_INLINE_ATTR void ieee802154_ll_set_cmd(ieee802154_ll_cmd_t cmd) { IEEE802154.cmd.cmd = cmd; @@ -193,6 +195,11 @@ FORCE_INLINE_ATTR ieee802154_ll_events ieee802154_ll_get_events(void) return (ieee802154_ll_events)(IEEE802154.event_status.events); } +FORCE_INLINE_ATTR bool ieee802154_ll_is_current_rx_frame(void) +{ + return (IEEE802154.rx_status.rx_state > IEEE802154_RX_STATUS_RECEIVE_SFD); +} + static inline void ieee802154_ll_enable_rx_abort_events(ieee802154_ll_rx_abort_events events) { IEEE802154.rx_abort_event_en.rx_abort_en |= events; diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 488e8e05d6..305d4f2ecb 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -45,9 +45,9 @@ menu "IEEE 802.15.4" bool "Enable the receive done handler feature" default n help - configure the receive done handler feature, when enabled, the user must call the - function `esp_ieee802154_receive_handle_done` to inform the 802.15.4 driver that - the received frame has been processed, so the frame space could be freed. + configure the receive done handler feature, when enabled, the user must call the + function `esp_ieee802154_receive_handle_done` to inform the 802.15.4 driver that + the received frame has been processed, so the frame space could be freed. config IEEE802154_CCA_MODE depends on IEEE802154_ENABLED diff --git a/components/ieee802154/driver/esp_ieee802154_debug.c b/components/ieee802154/driver/esp_ieee802154_debug.c index 2b172ad952..c8472c8315 100644 --- a/components/ieee802154/driver/esp_ieee802154_debug.c +++ b/components/ieee802154/driver/esp_ieee802154_debug.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -289,6 +289,11 @@ void ieee802154_tx_nums_update(void) s_ieee802154_txrx_statistic.tx.nums++; } +void ieee802154_tx_deferred_nums_update(void) +{ + s_ieee802154_txrx_statistic.tx.deferred_nums++; +} + void ieee802154_tx_break_coex_nums_update(void) { s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums++; @@ -302,9 +307,15 @@ void ieee802154_txrx_statistic_print(void) s_ieee802154_txrx_statistic.tx.abort.cca_failed_nums + s_ieee802154_txrx_statistic.tx.abort.cca_busy_nums; uint64_t tx_nums = s_ieee802154_txrx_statistic.tx.nums; + uint64_t tx_direct_num = tx_nums - s_ieee802154_txrx_statistic.tx.deferred_nums; + float tx_success_ratio = (tx_nums > 0 ? ((float)tx_success_nums / tx_nums) : 0); float tx_done_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.done_nums / tx_nums) : 0); float tx_abort_ratio = (tx_nums > 0 ? ((float)tx_abort_nums / tx_nums) : 0); + + float tx_direct_num_ratio = (tx_nums > 0 ? ((float)tx_direct_num / tx_nums) : 0); + float tx_deferred_num_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.deferred_nums / tx_nums) : 0); + float tx_abort_rx_ack_coex_break_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums / tx_nums) : 0); float tx_abort_rx_ack_timeout_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.rx_ack_timeout_nums / tx_nums) : 0); float tx_abort_tx_coex_break_ratio = (tx_nums > 0 ? ((float)s_ieee802154_txrx_statistic.tx.abort.tx_coex_break_nums / tx_nums) : 0); @@ -321,6 +332,10 @@ void ieee802154_txrx_statistic_print(void) ESP_LOGW(TAG, "+--------------------+-----------------------------------+--------------------------------------------------+"); ESP_LOGW(TAG, "|%-20s|%-10s%-15llu%9.2f%%|%-25s%-15llu%9.2f%%|", "", "Done:", s_ieee802154_txrx_statistic.tx.done_nums, tx_done_ratio*100, "Success:", tx_success_nums, tx_success_ratio*100); + ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_direct_num:", tx_direct_num, tx_direct_num_ratio*100); + ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); + ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "tx_deferred_num:", s_ieee802154_txrx_statistic.tx.deferred_nums, tx_deferred_num_ratio*100); ESP_LOGW(TAG, "+ +-----------------------------------+--------------------------------------------------+"); ESP_LOGW(TAG, "|%-20s|%-35s|%-25s%-15llu%9.2f%%|", "", "", "rx_ack_coex_break:", s_ieee802154_txrx_statistic.tx.abort.rx_ack_coex_break_nums, tx_abort_rx_ack_coex_break_ratio*100); ESP_LOGW(TAG, "+ + +--------------------------------------------------+"); diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 172f51532d..74d51ff89d 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,6 +75,15 @@ static intr_handle_t s_ieee802154_isr_handle = NULL; static esp_err_t ieee802154_sleep_init(void); static void next_operation(void); +static esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca); + +#if !CONFIG_IEEE802154_TEST +typedef struct { + const uint8_t *frame; + bool cca; +} pending_tx_t; +static pending_tx_t s_pending_tx = { 0 }; +#endif #if CONFIG_IEEE802154_RECEIVE_DONE_HANDLER static void ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) @@ -367,10 +376,18 @@ static void enable_rx(void) static IRAM_ATTR void next_operation(void) { - if (ieee802154_pib_get_rx_when_idle()) { - enable_rx(); - } else { - ieee802154_set_state(IEEE802154_STATE_IDLE); +#if !CONFIG_IEEE802154_TEST + if (s_pending_tx.frame) { + ieee802154_transmit_internal(s_pending_tx.frame, s_pending_tx.cca); + s_pending_tx.frame = NULL; + } else +#endif + { + if (ieee802154_pib_get_rx_when_idle()) { + enable_rx(); + } else { + ieee802154_set_state(IEEE802154_STATE_IDLE); + } } } @@ -802,7 +819,7 @@ IEEE802154_STATIC void tx_init(const uint8_t *frame) } } -esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) +static inline esp_err_t ieee802154_transmit_internal(const uint8_t *frame, bool cca) { IEEE802154_RF_ENABLE(); ieee802154_enter_critical(); @@ -819,10 +836,26 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) } ieee802154_exit_critical(); - return ESP_OK; } +esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) +{ +#if !CONFIG_IEEE802154_TEST + if ((s_ieee802154_state == IEEE802154_STATE_RX && ieee802154_ll_is_current_rx_frame()) + || s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) { + // If the current radio is processing an RX frame or sending an ACK, do not shut down the ongoing process. + // Instead, defer the transmission of the pending TX frame. + // Once the current process is completed, the pending transmit frame will be initiated. + s_pending_tx.frame = frame; + s_pending_tx.cca = cca; + IEEE802154_TX_DEFERRED_NUMS_UPDATE(); + return ESP_OK; + } +#endif + return ieee802154_transmit_internal(frame, cca); +} + static inline bool is_target_time_expired(uint32_t target, uint32_t now) { return (((now - target) & (1 << 31)) == 0); diff --git a/components/ieee802154/linker.lf b/components/ieee802154/linker.lf index 3c32c33352..b0a01b70c0 100644 --- a/components/ieee802154/linker.lf +++ b/components/ieee802154/linker.lf @@ -22,6 +22,10 @@ entries: esp_ieee802154_timer: ieee802154_timer0_stop (noflash) esp_ieee802154_timer: ieee802154_timer1_stop (noflash) esp_ieee802154_util: ieee802154_etm_channel_clear (noflash) + + if IEEE802154_DEBUG = y: + esp_ieee802154_debug (noflash) + if IEEE802154_TIMING_OPTIMIZATION = y: esp_ieee802154_dev: set_next_rx_buffer (noflash) esp_ieee802154_dev: stop_rx (noflash) diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h index 3288ac9e80..0d0268f422 100644 --- a/components/ieee802154/private_include/esp_ieee802154_util.h +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -185,6 +185,7 @@ void ieee802154_assert_print(void); typedef struct ieee802154_txrx_statistic{ struct { uint64_t nums; + uint64_t deferred_nums; uint64_t done_nums; struct { uint64_t rx_ack_coex_break_nums; // IEEE802154_RX_ACK_ABORT_COEX_CNT_REG @@ -218,6 +219,10 @@ typedef struct ieee802154_txrx_statistic{ ieee802154_txrx_statistic(a);\ } while(0) +#define IEEE802154_TX_DEFERRED_NUMS_UPDATE() do { \ + ieee802154_tx_deferred_nums_update();\ + } while(0) + #define IEEE802154_TX_NUMS_UPDATE() do { \ ieee802154_tx_nums_update();\ } while(0) @@ -230,10 +235,12 @@ void ieee802154_txrx_statistic_clear(void); void ieee802154_txrx_statistic_print(void); void ieee802154_txrx_statistic(ieee802154_ll_events events); void ieee802154_tx_nums_update(void); +void ieee802154_tx_deferred_nums_update(void); void ieee802154_tx_break_coex_nums_update(void); #else #define IEEE802154_TXRX_STATISTIC(a) #define IEEE802154_TX_NUMS_UPDATE() +#define IEEE802154_TX_DEFERRED_NUMS_UPDATE() #define IEEE802154_TXRX_STATISTIC_CLEAR() #define IEEE802154_TX_BREAK_COEX_NUMS_UPDATE() #endif // CONFIG_IEEE802154_TXRX_STATISTIC