From c72bbe13badfffbb7aa4a88188c43ab0fedc30cd Mon Sep 17 00:00:00 2001 From: zwx Date: Mon, 24 Mar 2025 19:07:53 +0800 Subject: [PATCH 1/2] feat(802.15.4): supported tx/rx frame dumping --- components/ieee802154/Kconfig | 16 ++++ .../ieee802154/driver/esp_ieee802154_debug.c | 41 ++++++++- .../private_include/esp_ieee802154_frame.h | 16 ++-- .../private_include/esp_ieee802154_util.h | 90 ++++++++++++++++--- 4 files changed, 144 insertions(+), 19 deletions(-) diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 1f1500a59a..e6da077da8 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -181,10 +181,26 @@ menu "IEEE 802.15.4" help set the record abort table size + config IEEE802154_RECORD_TXRX_FRAME + bool "Enable record txrx packets for debugging" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to record the tx and rx packets + + config IEEE802154_RECORD_TXRX_FRAME_SIZE + int "Record frame table size" + depends on IEEE802154_RECORD_TXRX_FRAME + range 1 50 + default 15 + help + set the record frame table size + config IEEE802154_TXRX_STATISTIC bool "Enable record tx/rx packets information for debugging" depends on IEEE802154_DEBUG default n help Enabling this option to record the tx and rx + endmenu # IEEE 802.15.4 diff --git a/components/ieee802154/driver/esp_ieee802154_debug.c b/components/ieee802154/driver/esp_ieee802154_debug.c index cd5041f910..21c315c4b9 100644 --- a/components/ieee802154/driver/esp_ieee802154_debug.c +++ b/components/ieee802154/driver/esp_ieee802154_debug.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -172,6 +172,18 @@ static char *ieee80154_tx_abort_reason_string[] = { #endif // CONFIG_IEEE802154_RECORD_EVENT #if CONFIG_IEEE802154_RECORD +#if CONFIG_IEEE802154_RECORD_TXRX_FRAME +static void ieee802154_dump_frame_print(const uint8_t *frame) +{ + for (uint8_t i = 1; i < frame[0]; i+=8) { + ESP_EARLY_LOGW(IEEE802154_TAG, "frag(%03d:%03d~%03d): %02x %02x %02x %02x %02x %02x %02x %02x", + frame[0], i, i+7, + frame[i], frame[i+1], frame[i+2], frame[i+3], + frame[i+4], frame[i+5], frame[i+6], frame[i+7]); + } +} +#endif // CONFIG_IEEE802154_RECORD_TXRX_FRAME + void ieee802154_record_print(void) { #if CONFIG_IEEE802154_RECORD_EVENT @@ -234,6 +246,33 @@ void ieee802154_record_print(void) } ESP_EARLY_LOGW(IEEE802154_TAG,"Print the record abort done."); #endif // CONFIG_IEEE802154_RECORD_ABORT + +#if CONFIG_IEEE802154_RECORD_TXRX_FRAME + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the dumping tx/rx frame, current frame index: %d", g_ieee802154_probe.frame_index); + for (uint8_t i = 0; i < IEEE802154_RECORD_TXRX_FRAME_SIZE; i++) { + if (g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_INVALID \ + || g_ieee802154_probe.frame[i].frame_type >= IEEE802154_RECORD_FRAME_TYPE_VALID_MAX) { + continue; + } + if (g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_RX \ + || g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_RX_ACK) { + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: %s frame, length: %d, buffer index: %d(%s buffer), timestamp: %lld, mac conf: %08x, packet:", + i, (g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_RX) ? "rx" : "rx ack", + g_ieee802154_probe.frame[i].dump_frame[0], g_ieee802154_probe.frame[i].rx_buffer_index, + (g_ieee802154_probe.frame[i].rx_buffer_index < 0 ? "Invalid" :\ + (g_ieee802154_probe.frame[i].rx_buffer_index == CONFIG_IEEE802154_RX_BUFFER_SIZE) ? "Stub" : "Valid"), + g_ieee802154_probe.frame[i].timestamp, g_ieee802154_probe.frame[i].mac_conf); + } else if (g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_TX \ + || g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_TX_ACK) { + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: %s frame, length: %d, timestamp: %lld, mac conf: %08x, packet:", + i, (g_ieee802154_probe.frame[i].frame_type == IEEE802154_RECORD_FRAME_TYPE_TX) ? "tx" : "tx ack", + g_ieee802154_probe.frame[i].dump_frame[0], g_ieee802154_probe.frame[i].timestamp, + g_ieee802154_probe.frame[i].mac_conf); + } + ieee802154_dump_frame_print(g_ieee802154_probe.frame[i].dump_frame); + } + ESP_EARLY_LOGW(IEEE802154_TAG, "Print the dumped tx/rx frame done."); +#endif // CONFIG_IEEE802154_RECORD_TXRX_FRAME } #endif // CONFIG_IEEE802154_RECORD diff --git a/components/ieee802154/private_include/esp_ieee802154_frame.h b/components/ieee802154/private_include/esp_ieee802154_frame.h index 497c1f7ee7..005c8ddaab 100644 --- a/components/ieee802154/private_include/esp_ieee802154_frame.h +++ b/components/ieee802154/private_include/esp_ieee802154_frame.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ extern "C" { #endif +#define IEEE802154_FRAME_MAX_LEN 127 + #define IEEE802154_FRAME_INVALID_OFFSET 0xff #define IEEE802154_FRAME_INVALID_ADDR_MODE 0xff @@ -139,9 +141,9 @@ bool ieee802154_frame_is_ack_required(const uint8_t *frame); * @param[out] addr The pointer to the address. * * @return - * - IEEE802154_FRAME_DST_MODE_NONE if destination adress mode is none. - * - IEEE802154_FRAME_DST_MODE_SHORT if destination adress mode is short. - * - IEEE802154_FRAME_DST_MODE_EXT if destination adress mode is extended. + * - IEEE802154_FRAME_DST_MODE_NONE if destination address mode is none. + * - IEEE802154_FRAME_DST_MODE_SHORT if destination address mode is short. + * - IEEE802154_FRAME_DST_MODE_EXT if destination address mode is extended. * */ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr); @@ -153,9 +155,9 @@ uint8_t ieee802154_frame_get_dst_addr(const uint8_t *frame, uint8_t *addr); * @param[out] addr The pointer to the address. * * @return - * - IEEE802154_FRAME_SRC_MODE_NONE if source adress mode is none. - * - IEEE802154_FRAME_SRC_MODE_SHORT if source adress mode is short. - * - IEEE802154_FRAME_SRC_MODE_EXT if source adress mode is extended. + * - IEEE802154_FRAME_SRC_MODE_NONE if source address mode is none. + * - IEEE802154_FRAME_SRC_MODE_SHORT if source address mode is short. + * - IEEE802154_FRAME_SRC_MODE_EXT if source address mode is extended. * */ uint8_t ieee802154_frame_get_src_addr(const uint8_t *frame, uint8_t *addr); diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h index 68a492ea59..b323367b9c 100644 --- a/components/ieee802154/private_include/esp_ieee802154_util.h +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -13,6 +13,7 @@ #include "esp_ieee802154_dev.h" #include "hal/ieee802154_ll.h" #include "esp_timer.h" +#include "soc/ieee802154_struct.h" #ifdef __cplusplus extern "C" { #endif @@ -36,8 +37,9 @@ static inline bool ieee802154_is_valid_channel(uint8_t channel) #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE #define IEEE802154_PROBE(a) do { \ IEEE802154_RECORD_EVENT(a); \ - ieee802154_record_abort(a); \ + IEEE802154_RECORD_ABORT(a); \ IEEE802154_TXRX_STATISTIC(a); \ + IEEE802154_RECORD_FRAME(a); \ } while(0) #if CONFIG_IEEE802154_RECORD_EVENT @@ -119,7 +121,7 @@ typedef struct { #if CONFIG_IEEE802154_RECORD_ABORT #define IEEE802154_ASSERT_RECORD_ABORT_SIZE CONFIG_IEEE802154_RECORD_ABORT_SIZE -#define ieee802154_record_abort(a) do { \ +#define IEEE802154_RECORD_ABORT(a) do { \ if (a == IEEE802154_EVENT_RX_ABORT) { \ g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].abort_reason.rx \ = ieee802154_ll_get_rx_abort_reason(); \ @@ -149,29 +151,95 @@ typedef struct { uint64_t timestamp; /*!< record timestamp*/ } ieee802154_abort_info_t; #else -#define ieee802154_record_abort(a) +#define IEEE802154_RECORD_ABORT(a) #endif // CONFIG_IEEE802154_RECORD_ABORT +#if CONFIG_IEEE802154_RECORD_TXRX_FRAME +#define IEEE802154_RECORD_TXRX_FRAME_SIZE CONFIG_IEEE802154_RECORD_TXRX_FRAME_SIZE +#define IEEE802154_RECORD_FRAME_TYPE_INVALID 0 +#define IEEE802154_RECORD_FRAME_TYPE_RX 1 +#define IEEE802154_RECORD_FRAME_TYPE_TX 2 +#define IEEE802154_RECORD_FRAME_TYPE_RX_ACK 3 +#define IEEE802154_RECORD_FRAME_TYPE_TX_ACK 4 +#define IEEE802154_RECORD_FRAME_TYPE_VALID_MAX 5 + +#define IEEE802154_DEBUG_RX_FRAME_DUMP(type) do {\ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].frame_type = type; \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].mac_conf = IEEE802154.conf.val; \ + if ((((uint8_t *)IEEE802154.dma_rx_addr - &s_rx_frame[0][0]) % IEEE802154_RX_FRAME_SIZE) != 0 \ + || (((uint8_t *)IEEE802154.dma_rx_addr - &s_rx_frame[0][0]) / IEEE802154_RX_FRAME_SIZE) > CONFIG_IEEE802154_RX_BUFFER_SIZE) { \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].rx_buffer_index = -1; \ + } else { \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].rx_buffer_index = \ + (((uint8_t *)IEEE802154.dma_rx_addr - &s_rx_frame[0][0]) / IEEE802154_RX_FRAME_SIZE); \ + } \ + memcpy(g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].dump_frame,\ + (void *)IEEE802154.dma_rx_addr, \ + IEEE802154_FRAME_MAX_LEN + 1); \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index++].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.frame_index = (g_ieee802154_probe.frame_index == IEEE802154_RECORD_TXRX_FRAME_SIZE) ? \ + 0 : g_ieee802154_probe.frame_index; \ + } while (0) + +#define IEEE802154_DEBUG_TX_FRAME_DUMP(type) do { \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].frame_type = type; \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].mac_conf = IEEE802154.conf.val; \ + memcpy(g_ieee802154_probe.frame[g_ieee802154_probe.frame_index].dump_frame,\ + (void *)IEEE802154.dma_tx_addr, \ + IEEE802154_FRAME_MAX_LEN + 1); \ + g_ieee802154_probe.frame[g_ieee802154_probe.frame_index++].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.frame_index = (g_ieee802154_probe.frame_index == IEEE802154_RECORD_TXRX_FRAME_SIZE) ? \ + 0 : g_ieee802154_probe.frame_index; \ + } while (0) + +#define IEEE802154_RECORD_FRAME(a) do { \ + if (a == IEEE802154_EVENT_RX_DONE) { \ + IEEE802154_DEBUG_RX_FRAME_DUMP(IEEE802154_RECORD_FRAME_TYPE_RX); \ + } else if (a == IEEE802154_EVENT_ACK_RX_DONE) { \ + IEEE802154_DEBUG_RX_FRAME_DUMP(IEEE802154_RECORD_FRAME_TYPE_RX_ACK); \ + } else if (a == IEEE802154_EVENT_TX_DONE) { \ + IEEE802154_DEBUG_TX_FRAME_DUMP(IEEE802154_RECORD_FRAME_TYPE_TX); \ + } else if (a == IEEE802154_EVENT_ACK_TX_DONE) { \ + if (s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK) { \ + IEEE802154_DEBUG_TX_FRAME_DUMP(IEEE802154_RECORD_FRAME_TYPE_TX_ACK); \ + } \ + } \ + } while(0) +typedef struct { + uint8_t frame_type; + uint8_t dump_frame[IEEE802154_FRAME_MAX_LEN + 1]; + int8_t rx_buffer_index; + uint32_t mac_conf; + uint64_t timestamp; +} ieee802154_txrx_frame_info_t; +#else +#define IEEE802154_RECORD_FRAME(a) +#endif // CONFIG_IEEE802154_RECORD_TXRX_FRAME + /** * @brief The table of recording IEEE802154 information. */ typedef struct { #if CONFIG_IEEE802154_RECORD_EVENT - ieee802154_event_info_t event[IEEE802154_ASSERT_RECORD_EVENT_SIZE]; /*!< record radio event */ - uint8_t event_index; /*!< the index of event */ + ieee802154_event_info_t event[IEEE802154_ASSERT_RECORD_EVENT_SIZE]; /*!< record radio event */ + uint8_t event_index; /*!< the index of event */ #endif // CONFIG_IEEE802154_RECORD_EVENT #if CONFIG_IEEE802154_RECORD_STATE - ieee802154_state_info_t state[IEEE802154_ASSERT_RECORD_STATE_SIZE]; /*!< record radio state */ - uint8_t state_index; /*!< the index of state */ + ieee802154_state_info_t state[IEEE802154_ASSERT_RECORD_STATE_SIZE]; /*!< record radio state */ + uint8_t state_index; /*!< the index of state */ #endif // CONFIG_IEEE802154_RECORD_STATE #if CONFIG_IEEE802154_RECORD_CMD - ieee802154_cmd_info_t cmd[IEEE802154_ASSERT_RECORD_CMD_SIZE]; /*!< record radio command */ - uint8_t cmd_index; /*!< the index of command */ + ieee802154_cmd_info_t cmd[IEEE802154_ASSERT_RECORD_CMD_SIZE]; /*!< record radio command */ + uint8_t cmd_index; /*!< the index of command */ #endif // CONFIG_IEEE802154_RECORD_CMD #if CONFIG_IEEE802154_RECORD_ABORT - ieee802154_abort_info_t abort[IEEE802154_ASSERT_RECORD_ABORT_SIZE]; /*!< record radio abort */ - uint8_t abort_index; /*!< the index of abort */ + ieee802154_abort_info_t abort[IEEE802154_ASSERT_RECORD_ABORT_SIZE]; /*!< record radio abort */ + uint8_t abort_index; /*!< the index of abort */ #endif // CONFIG_IEEE802154_RECORD_ABORT +#if CONFIG_IEEE802154_RECORD_TXRX_FRAME + ieee802154_txrx_frame_info_t frame[IEEE802154_RECORD_TXRX_FRAME_SIZE]; /*!< record txrx frame */ + uint8_t frame_index; /*!< the index of frame */ +#endif // CONFIG_IEEE802154_RECORD_TXRX_FRAME } ieee802154_probe_info_t; extern ieee802154_probe_info_t g_ieee802154_probe; From 75abe550a3793244d72a72473f1fd7a4af4c0e77 Mon Sep 17 00:00:00 2001 From: zwx Date: Wed, 2 Apr 2025 12:09:05 +0800 Subject: [PATCH 2/2] feat(802.15.4) add a build CI test for debugging feature --- .../ieee802154_cli/sdkconfig.ci.endbg | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 examples/ieee802154/ieee802154_cli/sdkconfig.ci.endbg diff --git a/examples/ieee802154/ieee802154_cli/sdkconfig.ci.endbg b/examples/ieee802154/ieee802154_cli/sdkconfig.ci.endbg new file mode 100644 index 0000000000..54734060df --- /dev/null +++ b/examples/ieee802154/ieee802154_cli/sdkconfig.ci.endbg @@ -0,0 +1,21 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y + +CONFIG_IEEE802154_DEBUG=y +CONFIG_IEEE802154_ASSERT=y +CONFIG_IEEE802154_RECORD=y +CONFIG_IEEE802154_RECORD_EVENT=y +CONFIG_IEEE802154_RECORD_EVENT_SIZE=30 +CONFIG_IEEE802154_RECORD_STATE=y +CONFIG_IEEE802154_RECORD_STATE_SIZE=10 +CONFIG_IEEE802154_RECORD_CMD=y +CONFIG_IEEE802154_RECORD_CMD_SIZE=10 +CONFIG_IEEE802154_RECORD_ABORT=y +CONFIG_IEEE802154_RECORD_ABORT_SIZE=10 +CONFIG_IEEE802154_RECORD_TXRX_FRAME=y +CONFIG_IEEE802154_RECORD_TXRX_FRAME_SIZE=15 + +CONFIG_ESP_INT_WDT=n + +CONFIG_FREERTOS_ISR_STACKSIZE=8192