From 82c7aab6fd4c57bcd2817531473b3d9231c9d80b Mon Sep 17 00:00:00 2001 From: zhangwenxu Date: Thu, 1 Jun 2023 17:07:51 +0800 Subject: [PATCH] ieee802154: add debug feature for driver --- components/ieee802154/CMakeLists.txt | 4 + components/ieee802154/Kconfig | 77 ++++++ .../ieee802154/driver/esp_ieee802154_ack.c | 3 +- .../ieee802154/driver/esp_ieee802154_debug.c | 239 ++++++++++++++++++ .../ieee802154/driver/esp_ieee802154_dev.c | 103 ++++---- .../private_include/esp_ieee802154_util.h | 163 ++++++++++++ 6 files changed, 538 insertions(+), 51 deletions(-) create mode 100644 components/ieee802154/driver/esp_ieee802154_debug.c diff --git a/components/ieee802154/CMakeLists.txt b/components/ieee802154/CMakeLists.txt index 5e6e51b9f57..fc7c6174f38 100644 --- a/components/ieee802154/CMakeLists.txt +++ b/components/ieee802154/CMakeLists.txt @@ -22,6 +22,10 @@ if(CONFIG_IEEE802154_ENABLED) endif() +if(CONFIG_IEEE802154_DEBUG) + list(APPEND srcs "driver/esp_ieee802154_debug.c") +endif() + idf_component_register( SRCS "${srcs}" INCLUDE_DIRS "${include}" diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 09aea764edf..aac79087012 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -82,4 +82,81 @@ menu "IEEE 802.15.4" help Enabling this option allows the IEEE802.15.4 module to be powered down during automatic light sleep, which reduces current consumption. + + menuconfig IEEE802154_DEBUG + bool "Enable IEEE802154 Debug" + default n + help + Enabling this option allows different kinds of IEEE802154 debug output. + All IEEE802154 debug features increase the size of the final binary. + + config IEEE802154_ASSERT + bool "Enrich the assert information with IEEE802154 state and event" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to add some probe codes in the driver, and these informations + will be printed when assert. + + config IEEE802154_RECORD_EVENT + bool "Enable record event information for debugging" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to record event, when assert, the recorded event will be printed. + + config IEEE802154_RECORD_EVENT_SIZE + int "Record event table size" + depends on IEEE802154_RECORD_EVENT + range 1 50 + default 30 + help + set the record event table size + + config IEEE802154_RECORD_STATE + bool "Enable record state information for debugging" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to record state, when assert, the recorded state will be printed. + + config IEEE802154_RECORD_STATE_SIZE + int "Record state table size" + depends on IEEE802154_RECORD_STATE + range 1 50 + default 10 + help + set the record state table size + + config IEEE802154_RECORD_CMD + bool "Enable record command information for debugging" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to record the command, when assert, the recorded + command will be printed. + + config IEEE802154_RECORD_CMD_SIZE + int "Record command table size" + depends on IEEE802154_RECORD_CMD + range 1 50 + default 10 + help + set the record command table size + + config IEEE802154_RECORD_ABORT + bool "Enable record abort information for debugging" + depends on IEEE802154_DEBUG + default n + help + Enabling this option to record the abort, when assert, the recorded + abort will be printed. + + config IEEE802154_RECORD_ABORT_SIZE + int "Record abort table size" + depends on IEEE802154_RECORD_ABORT + range 1 50 + default 10 + help + set the record abort table size endmenu # IEEE 802.15.4 diff --git a/components/ieee802154/driver/esp_ieee802154_ack.c b/components/ieee802154/driver/esp_ieee802154_ack.c index 99bdecff7da..2c96bdf99b6 100644 --- a/components/ieee802154/driver/esp_ieee802154_ack.c +++ b/components/ieee802154/driver/esp_ieee802154_ack.c @@ -13,6 +13,7 @@ #include "esp_ieee802154_frame.h" #include "esp_ieee802154_pib.h" #include "esp_ieee802154_types.h" +#include "esp_ieee802154_util.h" static ieee802154_pending_table_t ieee802154_pending_table; @@ -153,7 +154,7 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame) } break; default: - assert(false); + IEEE802154_ASSERT(false); } if (set_to_hw) { diff --git a/components/ieee802154/driver/esp_ieee802154_debug.c b/components/ieee802154/driver/esp_ieee802154_debug.c new file mode 100644 index 00000000000..6778b5efbc2 --- /dev/null +++ b/components/ieee802154/driver/esp_ieee802154_debug.c @@ -0,0 +1,239 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "hal/ieee802154_ll.h" +#include "esp_ieee802154_util.h" +#include "esp_log.h" + +#if CONFIG_IEEE802154_DEBUG +ieee802154_probe_info_t g_ieee802154_probe; +#define TAG "ieee802154_debug" + +#if CONFIG_IEEE802154_RECORD_EVENT +static char *ieee802154_get_event_string(ieee802154_ll_event_t events) +{ + char *event_string = ""; + switch (events) { + case IEEE802154_EVENT_TX_DONE: + event_string = "TX_DONE"; + break; + case IEEE802154_EVENT_RX_DONE: + event_string = "RX_DONE"; + break; + case IEEE802154_EVENT_ACK_TX_DONE: + event_string = "ACK_TX_DONE"; + break; + case IEEE802154_EVENT_ACK_RX_DONE: + event_string = "ACK_RX_DONE"; + break; + case IEEE802154_EVENT_RX_ABORT: + event_string = "RX_ABORT"; + break; + case IEEE802154_EVENT_TX_ABORT: + event_string = "TX_ABORT"; + break; + case IEEE802154_EVENT_ED_DONE: + event_string = "ED_DONE"; + break; + case IEEE802154_EVENT_TIMER0_OVERFLOW: + event_string = "TIMER0_OVERFLOW"; + break; + case IEEE802154_EVENT_TIMER1_OVERFLOW: + event_string = "TIMER1_OVERFLOW"; + break; + case IEEE802154_EVENT_CLOCK_COUNT_MATCH: + event_string = "CLOCK_COUNT_MATCH"; + break; + case IEEE802154_EVENT_TX_SFD_DONE: + event_string = "TX_SFD_DONE"; + break; + case IEEE802154_EVENT_RX_SFD_DONE: + event_string = "RX_SFD_DONE"; + break; + default: + event_string = "Multi events"; + break; + } + return event_string; +} +#endif // CONFIG_IEEE802154_RECORD_EVENT + +#if CONFIG_IEEE802154_RECORD_STATE || CONFIG_IEEE802154_RECORD_EVENT +static char *ieee802154_state_string[] = { + "DISABLE", + "IDLE", + "RX", + "TX_ACK", + "TX_ENH_ACK", + "TX_CCA", + "TX", + "DTM_TX", + "RX_ACK", + "ED", + "CCA", +}; +#endif // CONFIG_IEEE802154_RECORD_STATE + +#if CONFIG_IEEE802154_RECORD_CMD +static char *ieee802154_get_cmd_string(ieee802154_ll_cmd_t cmd) +{ + char *cmd_string = ""; + switch (cmd) { + case IEEE802154_CMD_TX_START: + cmd_string = "tx"; + break; + case IEEE802154_CMD_RX_START: + cmd_string = "rx"; + break; + case IEEE802154_CMD_CCA_TX_START: + cmd_string = "tx cca"; + break; + case IEEE802154_CMD_ED_START: + cmd_string = "ed"; + break; + case IEEE802154_CMD_STOP: + cmd_string = "stop"; + break; + case IEEE802154_CMD_TEST_TX_START: + cmd_string = "test tx"; + break; + case IEEE802154_CMD_TEST_RX_START: + cmd_string = "test rx"; + break; + case IEEE802154_CMD_TEST_STOP: + cmd_string = "test stop"; + break; + case IEEE802154_CMD_TIMER0_START: + cmd_string = "timer0 start"; + break; + case IEEE802154_CMD_TIMER0_STOP: + cmd_string = "timer0 stop"; + break; + case IEEE802154_CMD_TIMER1_START: + cmd_string = "timer1 start"; + break; + case IEEE802154_CMD_TIMER1_STOP: + cmd_string = "timer1 stop"; + break; + } + return cmd_string; +} +#endif // CONFIG_IEEE802154_RECORD_CMD + +#if CONFIG_IEEE802154_RECORD_EVENT || CONFIG_IEEE802154_RECORD_ABORT +static char *ieee80154_rx_abort_reason_string[] = { + "RSVD", // = 0, + "RX_STOP", // = 1, + "SFD_TIMEOUT", // = 2, + "CRC_ERROR ", // = 3, + "INVALID_LEN", // = 4, + "FILTER_FAIL", // = 5, + "NO_RSS ", // = 6, + "COEX_BREAK ", // = 7, + "UNEXPECTED_ACK", // = 8, + "RX_RESTART", // = 9, + "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", // = 10~15, + "TX_ACK_TIMEOUT", // = 16, + "TX_ACK_STOP", // = 17, + "TX_ACK_COEX_BREAK", // = 18, + "ENHACK_SECURITY_ERROR", // = 19, + "RSVD", "RSVD", "RSVD", "RSVD", // = 20~23 + "ED_ABORT", // = 24, + "ED_STOP", // = 25, + "ED_COEX_REJECT", // = 26, +}; + +static char *ieee80154_tx_abort_reason_string[] = { + "RSVD", // = 0, + "RX_ACK_STOP", // = 1, + "RX_ACK_SFD_TIMEOUT", // = 2, + "RX_ACK_CRC_ERROR", // = 3, + "RX_ACK_INVALID_LEN", // = 4, + "RX_ACK_FILTER_FAIL", // = 5, + "RX_ACK_NO_RSS", // = 6, + "RX_ACK_COEX_BREAK", // = 7, + "RX_ACK_TYPE_NOT_ACK", // = 8, + "RX_ACK_RESTART", // = 9, + "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", // = 10~15, + "RX_ACK_TIMEOUT", // = 16, + "TX_STOP", // = 17, + "TX_COEX_BREAK", // = 18, + "TX_SECURITY_ERROR", // = 19, + "RSVD", "RSVD", "RSVD", "RSVD", // = 20~23 + "CCA_FAILED", // = 24, + "CCA_BUSY", // = 25, +}; + +#endif // CONFIG_IEEE802154_RECORD_EVENT + +#if CONFIG_IEEE802154_ASSERT +void ieee802154_assert_print(void) +{ +#if CONFIG_IEEE802154_RECORD_EVENT + ESP_EARLY_LOGW(TAG, "Print the record event, current event index: %d", g_ieee802154_probe.event_index); + for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_EVENT_SIZE; i++) { + char event_log[200] = { 0 }; + char abort_log[100] = { 0 }; + snprintf(event_log, 200,"index %2d: event: 0x%4x, %15s, state:%10s, timestamp: %lld", i, g_ieee802154_probe.event[i].event, + ieee802154_get_event_string(g_ieee802154_probe.event[i].event), + ieee802154_state_string[g_ieee802154_probe.event[i].state], + g_ieee802154_probe.event[i].timestamp); + if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_RX_ABORT) { + snprintf(abort_log, 100, "rx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.rx, + ieee80154_rx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.rx]); + } else if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_TX_ABORT) { + snprintf(abort_log, 100, "tx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.tx, + ieee80154_tx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.tx]); + } + ESP_EARLY_LOGW(TAG, "%s %s", event_log, abort_log); + } + ESP_EARLY_LOGW(TAG,"Print the record event done.\n"); +#endif // CONFIG_IEEE802154_RECORD_EVENT + +#if CONFIG_IEEE802154_RECORD_STATE + ESP_EARLY_LOGW(TAG, "Print the record state, current state index: %d", g_ieee802154_probe.state_index); + for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_STATE_SIZE; i++) { + ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, state:%10s, timestamp: %lld", + i, g_ieee802154_probe.state[i].line_str, + ieee802154_state_string[g_ieee802154_probe.state[i].state], + g_ieee802154_probe.state[i].timestamp); + } + ESP_EARLY_LOGW(TAG,"Print the record state done.\n"); +#endif // CONFIG_IEEE802154_RECORD_STATE + +#if CONFIG_IEEE802154_RECORD_CMD + ESP_EARLY_LOGW(TAG, "Print the record cmd, current cmd index: %d", g_ieee802154_probe.cmd_index); + for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_CMD_SIZE; i++) { + ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, cmd:%10s, timestamp: %lld", + i, g_ieee802154_probe.cmd[i].line_str, + ieee802154_get_cmd_string(g_ieee802154_probe.cmd[i].cmd), + g_ieee802154_probe.cmd[i].timestamp); + } + ESP_EARLY_LOGW(TAG,"Print the record cmd done.\n"); +#endif // CONFIG_IEEE802154_RECORD_CMD + +#if CONFIG_IEEE802154_RECORD_ABORT + ESP_EARLY_LOGW(TAG, "Print the record abort, current abort index: %d", g_ieee802154_probe.abort_index); + for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_ABORT_SIZE; i++) { + if (g_ieee802154_probe.abort[i].is_tx_abort) { + ESP_EARLY_LOGW(TAG, "index %2d: tx abort: %4x, %15s, timestamp: %lld", + i, g_ieee802154_probe.abort[i].abort_reason.tx, + ieee80154_tx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.tx], + g_ieee802154_probe.abort[i].timestamp); + } else { + ESP_EARLY_LOGW(TAG, "index %2d: rx abort: %4x, %15s, timestamp: %lld", + i, g_ieee802154_probe.abort[i].abort_reason.rx, + ieee80154_rx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.rx], + g_ieee802154_probe.abort[i].timestamp); + } + } + ESP_EARLY_LOGW(TAG,"Print the record abort done.\n"); +#endif // CONFIG_IEEE802154_RECORD_ABORT +} +#endif // CONFIG_IEEE802154_ASSERT + +#endif // CONFIG_IEEE802154_DEBUG diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index dd428c6f292..042c8b5d070 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -102,7 +102,7 @@ static bool stop_rx(void) { ieee802154_ll_events events; - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); events = ieee802154_ll_get_events(); if (events & IEEE802154_EVENT_RX_DONE) { @@ -116,7 +116,7 @@ static bool stop_rx(void) static bool stop_tx_ack(void) { - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); @@ -129,7 +129,7 @@ static bool stop_tx(void) { ieee802154_ll_events events; - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); events = ieee802154_ll_get_events(); @@ -151,7 +151,7 @@ static bool stop_tx(void) static bool stop_cca(void) { - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT); return true; } @@ -167,7 +167,7 @@ static bool stop_rx_ack(void) { ieee802154_ll_events events; - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); events = ieee802154_ll_get_events(); @@ -187,7 +187,7 @@ static bool stop_rx_ack(void) static bool stop_ed(void) { - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT); @@ -238,7 +238,7 @@ IEEE802154_STATIC bool stop_current_operation(void) break; default: - assert(false); + IEEE802154_ASSERT(false); break; } @@ -250,9 +250,9 @@ static void enable_rx(void) set_next_rx_buffer(); IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX); - ieee802154_ll_set_cmd(IEEE802154_CMD_RX_START); + ieee802154_set_cmd(IEEE802154_CMD_RX_START); - s_ieee802154_state = IEEE802154_STATE_RX; + ieee802154_set_state(IEEE802154_STATE_RX); } static IRAM_ATTR void next_operation(void) @@ -260,7 +260,7 @@ static IRAM_ATTR void next_operation(void) if (ieee802154_pib_get_rx_when_idle()) { enable_rx(); } else { - s_ieee802154_state = IEEE802154_STATE_IDLE; + ieee802154_set_state(IEEE802154_STATE_IDLE); } } @@ -295,7 +295,7 @@ static IRAM_ATTR void isr_handle_tx_done(void) next_operation(); } else if (s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA) { if (ieee802154_frame_is_ack_required(s_tx_frame) && ieee802154_ll_get_rx_auto_ack()) { - s_ieee802154_state = IEEE802154_STATE_RX_ACK; + ieee802154_set_state(IEEE802154_STATE_RX_ACK); receive_ack_timeout_timer_start(200000); // 200ms for receive ack timeout } else { esp_ieee802154_transmit_done(s_tx_frame, NULL, NULL); @@ -315,7 +315,7 @@ static IRAM_ATTR void isr_handle_rx_done(void) && ieee802154_ll_get_tx_auto_ack()) { // auto tx ack only works for the frame with version 0b00 and 0b01 s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); - s_ieee802154_state = IEEE802154_STATE_TX_ACK; + ieee802154_set_state(IEEE802154_STATE_TX_ACK); } else if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) == IEEE802154_FRAME_VERSION_2 && ieee802154_ll_get_tx_enhance_ack()) { s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]); @@ -327,11 +327,11 @@ static IRAM_ATTR void isr_handle_rx_done(void) s_tx_frame = s_enh_ack_frame; ieee802154_sec_update(); ieee802154_ll_enhack_generate_done_notify(); - s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK; + ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK); #endif } else { // Stop current process if generator returns errors. - ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); + ieee802154_set_cmd(IEEE802154_CMD_STOP); esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); next_operation(); } @@ -375,25 +375,25 @@ static IRAM_ATTR void isr_handle_rx_abort(void) case IEEE802154_RX_ABORT_BY_NO_RSS: case IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK: case IEEE802154_RX_ABORT_BY_RX_RESTART: - assert(s_ieee802154_state == IEEE802154_STATE_RX); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX); #if CONFIG_IEEE802154_TEST esp_ieee802154_receive_failed(rx_status); next_operation(); #endif break; case IEEE802154_RX_ABORT_BY_COEX_BREAK: - assert(s_ieee802154_state == IEEE802154_STATE_RX); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX); esp_ieee802154_receive_failed(rx_status); break; case IEEE802154_RX_ABORT_BY_ED_ABORT: case IEEE802154_RX_ABORT_BY_ED_COEX_REJECT: - assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); esp_ieee802154_ed_failed(rx_status); next_operation(); break; case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT: case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK: - assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); #if !CONFIG_IEEE802154_TEST esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); next_operation(); @@ -402,7 +402,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void) #endif break; case IEEE802154_RX_ABORT_BY_ENHACK_SECURITY_ERROR: - assert(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); #if !CONFIG_IEEE802154_TEST esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]); next_operation(); @@ -411,7 +411,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void) #endif break; default: - assert(false); + IEEE802154_ASSERT(false); } } @@ -432,37 +432,37 @@ static IRAM_ATTR void isr_handle_tx_abort(void) case IEEE802154_TX_ABORT_BY_RX_ACK_COEX_BREAK: case IEEE802154_TX_ABORT_BY_RX_ACK_TYPE_NOT_ACK: case IEEE802154_TX_ABORT_BY_RX_ACK_RESTART: - assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK); break; case IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT: - assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK); next_operation(); break; case IEEE802154_TX_ABORT_BY_TX_COEX_BREAK: - assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST); next_operation(); break; case IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR: - assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY); next_operation(); break; case IEEE802154_TX_ABORT_BY_CCA_FAILED: - assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT); next_operation(); break; case IEEE802154_TX_ABORT_BY_CCA_BUSY: - assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA); esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY); next_operation(); break; default: - assert(false); + IEEE802154_ASSERT(false); break; } } @@ -482,11 +482,13 @@ static void ieee802154_isr(void *arg) { ieee802154_ll_events events = ieee802154_ll_get_events(); + IEEE802154_PROBE(events); + ieee802154_ll_clear_events(events); if (events & IEEE802154_EVENT_RX_SFD_DONE) { // IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay - assert(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); s_rx_frame_info[s_rx_index].timestamp = esp_timer_get_time(); esp_ieee802154_receive_sfd_done(); @@ -496,7 +498,7 @@ static void ieee802154_isr(void *arg) if (events & IEEE802154_EVENT_TX_SFD_DONE) { // ZB-81: IEEE802154_STATE_TX_ACK is also a possible state - assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ACK); esp_ieee802154_transmit_sfd_done(s_tx_frame); @@ -504,7 +506,7 @@ static void ieee802154_isr(void *arg) } if (events & IEEE802154_EVENT_TX_DONE) { - assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); isr_handle_tx_done(); @@ -512,7 +514,7 @@ static void ieee802154_isr(void *arg) } if (events & IEEE802154_EVENT_RX_DONE) { - assert(s_ieee802154_state == IEEE802154_STATE_RX); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX); isr_handle_rx_done(); @@ -521,7 +523,7 @@ static void ieee802154_isr(void *arg) if (events & IEEE802154_EVENT_ACK_TX_DONE) { // IEEE802154_STATE_RX for isr processing delay - assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); isr_handle_ack_tx_done(); @@ -530,7 +532,7 @@ static void ieee802154_isr(void *arg) if (events & IEEE802154_EVENT_ACK_RX_DONE) { // IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay - assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK); isr_handle_ack_rx_done(); @@ -550,7 +552,7 @@ static void ieee802154_isr(void *arg) } if (events & IEEE802154_EVENT_ED_DONE) { - assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA); isr_handle_ed_done(); @@ -559,10 +561,10 @@ static void ieee802154_isr(void *arg) if (events & IEEE802154_EVENT_TIMER0_OVERFLOW) { #if !CONFIG_IEEE802154_TEST - assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK); + IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK); #else extern bool ieee802154_timer0_test; - assert(ieee802154_timer0_test || s_ieee802154_state == IEEE802154_STATE_RX_ACK); + IEEE802154_ASSERT(ieee802154_timer0_test || s_ieee802154_state == IEEE802154_STATE_RX_ACK); #endif isr_handle_timer0_done(); @@ -576,7 +578,7 @@ static void ieee802154_isr(void *arg) } // all events should be handled - assert(events == 0); + IEEE802154_ASSERT(events == 0); } @@ -599,7 +601,7 @@ void ieee802154_enable(void) void ieee802154_disable(void) { modem_clock_module_disable(ieee802154_periph.module); - s_ieee802154_state = IEEE802154_STATE_DISABLE; + ieee802154_set_state(IEEE802154_STATE_DISABLE); } esp_err_t ieee802154_mac_init(void) @@ -631,6 +633,7 @@ esp_err_t ieee802154_mac_init(void) #endif memset(s_rx_frame, 0, sizeof(s_rx_frame)); + ieee802154_set_state(IEEE802154_STATE_IDLE); // TODO: Add flags for IEEE802154 ISR allocating. TZ-102 ret = esp_intr_alloc(ieee802154_periph.irq_id, 0, ieee802154_isr, NULL, NULL); @@ -645,7 +648,7 @@ IEEE802154_STATIC void start_ed(uint32_t duration) { ieee802154_ll_enable_events(IEEE802154_EVENT_ED_DONE); ieee802154_ll_set_ed_duration(duration); - ieee802154_ll_set_cmd(IEEE802154_CMD_ED_START); + ieee802154_set_cmd(IEEE802154_CMD_ED_START); } IEEE802154_STATIC void tx_init(const uint8_t *frame) @@ -671,11 +674,11 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca) IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX); if (cca) { - ieee802154_ll_set_cmd(IEEE802154_CMD_CCA_TX_START); - s_ieee802154_state = IEEE802154_STATE_TX_CCA; + ieee802154_set_cmd(IEEE802154_CMD_CCA_TX_START); + ieee802154_set_state(IEEE802154_STATE_TX_CCA); } else { - ieee802154_ll_set_cmd(IEEE802154_CMD_TX_START); - s_ieee802154_state = IEEE802154_STATE_TX; + ieee802154_set_cmd(IEEE802154_CMD_TX_START); + ieee802154_set_state(IEEE802154_STATE_TX); } ieee802154_exit_critical(); @@ -696,7 +699,7 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX_AT); if (cca) { tx_target_time = time - IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US; - s_ieee802154_state = IEEE802154_STATE_TX_CCA; + ieee802154_set_state(IEEE802154_STATE_TX_CCA); ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_ED_TRIG_TX); current_time = (uint32_t)esp_timer_get_time(); @@ -706,9 +709,9 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time) } else { tx_target_time = time - IEEE802154_TX_RAMPUP_TIME_US; if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_ACK && ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) { - s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK; + ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK); } else { - s_ieee802154_state = IEEE802154_STATE_TX; + ieee802154_set_state(IEEE802154_STATE_TX); } ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_TX_START); @@ -749,7 +752,7 @@ esp_err_t ieee802154_receive_at(uint32_t time) rx_init(); IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX_AT); set_next_rx_buffer(); - s_ieee802154_state = IEEE802154_STATE_RX; + ieee802154_set_state(IEEE802154_STATE_RX); ieee802154_enter_critical(); ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_RX_START); current_time = (uint32_t)esp_timer_get_time(); @@ -801,7 +804,7 @@ esp_err_t ieee802154_sleep(void) ieee802154_enter_critical(); stop_current_operation(); - s_ieee802154_state = IEEE802154_STATE_SLEEP; + ieee802154_set_state(IEEE802154_STATE_IDLE); ieee802154_exit_critical(); return ESP_OK; @@ -816,7 +819,7 @@ esp_err_t ieee802154_energy_detect(uint32_t duration) ieee802154_pib_update(); start_ed(duration); - s_ieee802154_state = IEEE802154_STATE_ED; + ieee802154_set_state(IEEE802154_STATE_ED); ieee802154_exit_critical(); return ESP_OK; @@ -831,7 +834,7 @@ esp_err_t ieee802154_cca(void) ieee802154_pib_update(); start_ed(CCA_DETECTION_TIME); - s_ieee802154_state = IEEE802154_STATE_CCA; + ieee802154_set_state(IEEE802154_STATE_CCA); ieee802154_exit_critical(); return ESP_OK; diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h index a41576c5aba..61348842519 100644 --- a/components/ieee802154/private_include/esp_ieee802154_util.h +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -8,9 +8,172 @@ #include #include +#include "esp_ieee802154_dev.h" +#include "hal/ieee802154_ll.h" +#include "esp_timer.h" #ifdef __cplusplus extern "C" { #endif + +#define IEEE802154_PROBE(a) do { \ + IEEE802154_RECORD_EVENT(a); \ + ieee802154_record_abort(a); \ + } while(0) + +#if CONFIG_IEEE802154_RECORD_EVENT +#define IEEE802154_ASSERT_RECORD_EVENT_SIZE CONFIG_IEEE802154_RECORD_EVENT_SIZE +#define IEEE802154_RECORD_EVENT(a) do { \ + g_ieee802154_probe.event[g_ieee802154_probe.event_index].event = a; \ + g_ieee802154_probe.event[g_ieee802154_probe.event_index].state = ieee802154_get_state(); \ + if (a == IEEE802154_EVENT_RX_ABORT) { \ + g_ieee802154_probe.event[g_ieee802154_probe.event_index].abort_reason.rx \ + = ieee802154_ll_get_rx_abort_reason(); \ + } else if (a == IEEE802154_EVENT_TX_ABORT) { \ + g_ieee802154_probe.event[g_ieee802154_probe.event_index].abort_reason.tx \ + = ieee802154_ll_get_tx_abort_reason(); \ + } \ + g_ieee802154_probe.event[g_ieee802154_probe.event_index++].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.event_index = (g_ieee802154_probe.event_index == IEEE802154_ASSERT_RECORD_EVENT_SIZE) ? \ + 0 : g_ieee802154_probe.event_index; \ + } while(0) + +/** + * @brief The table of recording IEEE802154 event command. + */ +typedef struct { + ieee802154_ll_events event; /*!< record current radio event */ + ieee802154_state_t state; /*!< record current radio state */ + union { + ieee802154_ll_rx_abort_reason_t rx; + ieee802154_ll_tx_abort_reason_t tx; + } abort_reason; /*!< record current radio abort reason */ + uint64_t timestamp; /*!< record timestamp*/ +} ieee802154_event_info_t; +#else +#define IEEE802154_RECORD_EVENT(a) +#endif // CONFIG_IEEE802154_RECORD_EVENT + +#if CONFIG_IEEE802154_RECORD_STATE +#define IEEE802154_ASSERT_RECORD_STATE_SIZE CONFIG_IEEE802154_RECORD_STATE_SIZE +#define ieee802154_set_state(a) do { s_ieee802154_state = a; \ + sprintf(g_ieee802154_probe.state[g_ieee802154_probe.state_index].line_str, "%d", __LINE__); \ + g_ieee802154_probe.state[g_ieee802154_probe.state_index].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.state[g_ieee802154_probe.state_index++].state = a; \ + g_ieee802154_probe.state_index = \ + (g_ieee802154_probe.state_index == IEEE802154_ASSERT_RECORD_STATE_SIZE) ? 0 : g_ieee802154_probe.state_index; \ + } while(0) + +/** + * @brief The table of recording IEEE802154 state command. + */ +typedef struct { + char line_str[5]; /*!< record which line in esp_ieee802154_dev.c changes the state */ + ieee802154_state_t state; /*!< record current radio state */ + uint64_t timestamp; /*!< record timestamp */ +} ieee802154_state_info_t; +#else +#define ieee802154_set_state(state) (s_ieee802154_state = state) +#endif // CONFIG_IEEE802154_RECORD_STATE + +#if CONFIG_IEEE802154_RECORD_CMD +#define IEEE802154_ASSERT_RECORD_CMD_SIZE CONFIG_IEEE802154_RECORD_CMD_SIZE +#define ieee802154_set_cmd(a) do { ieee802154_ll_set_cmd(a); \ + sprintf(g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].line_str, "%d", __LINE__); \ + g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index++].cmd = a; \ + g_ieee802154_probe.cmd_index = \ + (g_ieee802154_probe.cmd_index == IEEE802154_ASSERT_RECORD_CMD_SIZE) ? 0 : g_ieee802154_probe.cmd_index; \ + } while(0) + +/** + * @brief The table of recording IEEE802154 radio command. + */ +typedef struct { + char line_str[5]; /*!< record which line in esp_ieee802154_dev.c set the command */ + ieee802154_ll_cmd_t cmd; /*!< record current command */ + uint64_t timestamp; /*!< record timestamp */ +} ieee802154_cmd_info_t; +#else +#define ieee802154_set_cmd(cmd) ieee802154_ll_set_cmd(cmd) +#endif //CONFIG_IEEE802154_RECORD_CMD + +#if CONFIG_IEEE802154_RECORD_ABORT +#define IEEE802154_ASSERT_RECORD_ABORT_SIZE CONFIG_IEEE802154_RECORD_ABORT_SIZE +#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(); \ + g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].is_tx_abort = 0; \ + g_ieee802154_probe.abort[g_ieee802154_probe.abort_index++].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.abort_index = (g_ieee802154_probe.abort_index == IEEE802154_ASSERT_RECORD_ABORT_SIZE) ? \ + 0 : g_ieee802154_probe.abort_index; \ + } else if (a == IEEE802154_EVENT_TX_ABORT) { \ + g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].abort_reason.tx \ + = ieee802154_ll_get_tx_abort_reason();\ + g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].is_tx_abort = 1; \ + g_ieee802154_probe.abort[g_ieee802154_probe.abort_index++].timestamp = esp_timer_get_time(); \ + g_ieee802154_probe.abort_index = (g_ieee802154_probe.abort_index == IEEE802154_ASSERT_RECORD_ABORT_SIZE) ? \ + 0 : g_ieee802154_probe.abort_index; \ + } \ + } while(0) + +/** + * @brief The table of recording IEEE802154 radio abort. + */ +typedef struct { + bool is_tx_abort; /*!< record current abort type */ + union { + ieee802154_ll_rx_abort_reason_t rx; + ieee802154_ll_tx_abort_reason_t tx; + } abort_reason; /*!< record current radio abort reason */ + uint64_t timestamp; /*!< record timestamp*/ +} ieee802154_abort_info_t; +#else +#define ieee802154_record_abort(a) +#endif // CONFIG_IEEE802154_RECORD_ABORT + +/** + * @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 */ +#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 */ +#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 */ +#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 */ +#endif // CONFIG_IEEE802154_RECORD_ABORT +} ieee802154_probe_info_t; + +extern ieee802154_probe_info_t g_ieee802154_probe; + +#if CONFIG_IEEE802154_ASSERT +/** + * @brief This function print rich information, which is useful for debug. + * Only can be used when `IEEE802154_ASSERT` is enabled. + * + */ +void ieee802154_assert_print(void); +#define IEEE802154_ASSERT(a) do { \ + if(!(a)) { \ + ieee802154_assert_print(); \ + assert(a); \ + } \ + } while (0) +#else // CONFIG_IEEE802154_ASSERT +#define IEEE802154_ASSERT(a) assert(a) +#endif // CONFIG_IEEE802154_ASSERT + + // TODO: replace etm code using common interface #define IEEE802154_ETM_CHANNEL0 0