feat(802.15.4): introduce pending tx while rx feature

This commit is contained in:
zwx 2024-01-11 15:36:44 +08:00 committed by Xu Si Yu
parent 08f462dc0e
commit 2f988d08de
6 changed files with 79 additions and 13 deletions

View File

@ -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
*/
@ -162,6 +162,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;
@ -187,6 +189,11 @@ FORCE_INLINE_ATTR ieee802154_ll_events ieee802154_ll_get_events(void)
return 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;

View File

@ -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

View File

@ -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, "+ + +--------------------------------------------------+");

View File

@ -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);

View File

@ -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)

View File

@ -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