From 7e040539d5ca75381114bdedc2c33f25cfbf3ea6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 11:28:28 +0200 Subject: [PATCH 1/8] nimble/ll/dtm: Remove scheduler first when stopping DTM It should be safer to begin stopping DTM by removing scheduler item so it does not fire while we are stopping things. --- nimble/controller/src/ble_ll_dtm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 8792ef337..fb504a131 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -389,6 +389,8 @@ ble_ll_dtm_ctx_free(struct dtm_ctx * ctx) } OS_EXIT_CRITICAL(sr); + ble_ll_sched_rmv_elem(&ctx->sch); + ble_phy_disable(); ble_phy_disable_dtm(); ble_ll_state_set(BLE_LL_STATE_STANDBY); @@ -396,7 +398,6 @@ ble_ll_dtm_ctx_free(struct dtm_ctx * ctx) ble_ll_xcvr_rfclk_stop(); #endif - ble_ll_sched_rmv_elem(&ctx->sch); os_mbuf_free_chain(ctx->om); memset(ctx, 0, sizeof(*ctx)); } From c5ab2b48f5019ea6756eaff6d26d92afa4e202ca Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 11:59:05 +0200 Subject: [PATCH 2/8] nimble/ll/dtm: Add stat for TX reschedule --- nimble/controller/src/ble_ll_dtm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index fb504a131..4e2ed3f48 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -23,12 +23,22 @@ #include "assert.h" #include "os/os.h" +#include "stats/stats.h" #include "controller/ble_ll.h" #include "controller/ble_phy.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_xcvr.h" #include "ble_ll_dtm_priv.h" +STATS_SECT_START(ble_ll_dtm_stats) + STATS_SECT_ENTRY(tx_failed) +STATS_SECT_END +STATS_SECT_DECL(ble_ll_dtm_stats) ble_ll_dtm_stats; + +STATS_NAME_START(ble_ll_dtm_stats) + STATS_NAME(ble_ll_dtm_stats, tx_failed) +STATS_NAME_END(ble_phy_stats) + struct dtm_ctx { uint8_t payload_packet; uint8_t itvl_rem_usec; @@ -217,6 +227,9 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) resched: /* Reschedule from LL task if late for this PDU */ ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ctx->evt); + + STATS_INC(ble_ll_dtm_stats, tx_failed); + return BLE_LL_SCHED_STATE_DONE; } From 430ef71fc0e5669c7f30abc12d00b8ab2ec6f49a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 11:59:53 +0200 Subject: [PATCH 3/8] nimble/ll/dtm: Change event callback name We'll have more of them soon. --- nimble/controller/src/ble_ll_dtm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 4e2ed3f48..955e404e7 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -151,7 +151,7 @@ ble_ll_dtm_set_next(struct dtm_ctx *ctx) } static void -ble_ll_dtm_event(struct ble_npl_event *evt) { +ble_ll_dtm_ev_tx_resched_cb(struct ble_npl_event *evt) { /* It is called in LL context */ struct dtm_ctx *ctx = ble_npl_event_get_arg(evt); int rc; @@ -326,7 +326,7 @@ schedule: os_cputime_usecs_to_ticks(5000); /* Prepare os_event */ - ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_event, + ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_ev_tx_resched_cb, &g_ble_ll_dtm_ctx); ble_ll_dtm_calculate_itvl(&g_ble_ll_dtm_ctx, len, phy_mode); From f95b4b35fe1983622f7b946f70822207a3d19401 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 12:03:37 +0200 Subject: [PATCH 4/8] nimble/ll/dtm: Remove unnecessary assert HCI command will simply fail, no need to assert here. --- nimble/controller/src/ble_ll_dtm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 955e404e7..104b90da0 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -381,7 +381,6 @@ ble_ll_dtm_rx_create_ctx(uint8_t rf_channel, uint8_t phy_mode) g_ble_ll_dtm_ctx.active = 1; if (ble_ll_dtm_rx_start() != 0) { - BLE_LL_ASSERT(0); return 1; } From 7c93cf86e9529b1614fac9dbf06b93a803ce6500 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 12:07:48 +0200 Subject: [PATCH 5/8] nimble/ll/dtm: Try to restart RX if failed due to radio error --- nimble/controller/src/ble_ll_dtm.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 104b90da0..7f6c37651 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -32,11 +32,13 @@ STATS_SECT_START(ble_ll_dtm_stats) STATS_SECT_ENTRY(tx_failed) + STATS_SECT_ENTRY(rx_failed) STATS_SECT_END STATS_SECT_DECL(ble_ll_dtm_stats) ble_ll_dtm_stats; STATS_NAME_START(ble_ll_dtm_stats) STATS_NAME(ble_ll_dtm_stats, tx_failed) + STATS_NAME(ble_ll_dtm_stats, rx_failed) STATS_NAME_END(ble_phy_stats) struct dtm_ctx { @@ -169,6 +171,16 @@ ble_ll_dtm_ev_tx_resched_cb(struct ble_npl_event *evt) { BLE_LL_ASSERT(rc == 0); } +static int ble_ll_dtm_rx_start(void); + +static void +ble_ll_dtm_ev_rx_restart_cb(struct ble_npl_event *evt) { + if (ble_ll_dtm_rx_start() != 0) { + ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + STATS_INC(ble_ll_dtm_stats, rx_failed); + } +} + static void ble_ll_dtm_tx_done(void *arg) { @@ -380,6 +392,9 @@ ble_ll_dtm_rx_create_ctx(uint8_t rf_channel, uint8_t phy_mode) g_ble_ll_dtm_ctx.rf_channel = rf_channel; g_ble_ll_dtm_ctx.active = 1; + ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_ev_rx_restart_cb, + NULL); + if (ble_ll_dtm_rx_start() != 0) { return 1; } @@ -525,7 +540,8 @@ ble_ll_dtm_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) } if (ble_ll_dtm_rx_start() != 0) { - BLE_LL_ASSERT(0); + ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + STATS_INC(ble_ll_dtm_stats, rx_failed); } } From 71c9564458b745b69f70140e0911fa0670713c3d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 13:27:28 +0200 Subject: [PATCH 6/8] nimble/ll/dtm: Register stats properly --- nimble/controller/include/controller/ble_ll.h | 4 ++++ nimble/controller/src/ble_ll.c | 4 ++++ nimble/controller/src/ble_ll_dtm.c | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index eaa30f38d..0be058e43 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -527,6 +527,10 @@ extern uint32_t g_bletest_IVm; extern uint32_t g_bletest_IVs; #endif +#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +void ble_ll_dtm_init(); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 42bd73d47..50e1749f9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1580,4 +1580,8 @@ ble_ll_init(void) SYSINIT_PANIC_ASSERT(rc == 0); ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL); + +#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) + ble_ll_dtm_init(); +#endif } diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 7f6c37651..aabc8b846 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -578,4 +578,16 @@ ble_ll_dtm_reset(void) { ble_ll_dtm_ctx_free(&g_ble_ll_dtm_ctx); } + +void +ble_ll_dtm_init(void) +{ + int rc; + + rc = stats_init_and_reg(STATS_HDR(ble_ll_dtm_stats), + STATS_SIZE_INIT_PARMS(ble_ll_dtm_stats, STATS_SIZE_32), + STATS_NAME_INIT_PARMS(ble_ll_dtm_stats), + "ble_ll_dtm"); + SYSINIT_PANIC_ASSERT(rc == 0); +} #endif From dd403a661d226ddd7564daf033d04dc5225ac8b6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 16:45:17 +0200 Subject: [PATCH 7/8] nimble/ll/dtm: Add stat to count RX packets in real-time --- nimble/controller/src/ble_ll_dtm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index aabc8b846..d586b7112 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -31,12 +31,14 @@ #include "ble_ll_dtm_priv.h" STATS_SECT_START(ble_ll_dtm_stats) + STATS_SECT_ENTRY(rx_count) STATS_SECT_ENTRY(tx_failed) STATS_SECT_ENTRY(rx_failed) STATS_SECT_END STATS_SECT_DECL(ble_ll_dtm_stats) ble_ll_dtm_stats; STATS_NAME_START(ble_ll_dtm_stats) + STATS_NAME(ble_ll_dtm_stats, rx_count) STATS_NAME(ble_ll_dtm_stats, tx_failed) STATS_NAME(ble_ll_dtm_stats, rx_failed) STATS_NAME_END(ble_phy_stats) @@ -392,6 +394,8 @@ ble_ll_dtm_rx_create_ctx(uint8_t rf_channel, uint8_t phy_mode) g_ble_ll_dtm_ctx.rf_channel = rf_channel; g_ble_ll_dtm_ctx.active = 1; + STATS_CLEAR(ble_ll_dtm_stats, rx_count); + ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_ev_rx_restart_cb, NULL); @@ -537,6 +541,7 @@ ble_ll_dtm_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) if (BLE_MBUF_HDR_CRC_OK(hdr)) { /* XXX Compare data. */ g_ble_ll_dtm_ctx.num_of_packets++; + STATS_INC(ble_ll_dtm_stats, rx_count); } if (ble_ll_dtm_rx_start() != 0) { From 1634272c0312b15b9996da17be1ed01a3378d4e6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Sep 2018 16:45:23 +0200 Subject: [PATCH 8/8] nimble/ll/dtm: Start RX with interrupts disabled It can happen that if we are interrupted when setting things for RX, we will be stuck with radio unconfigured. For now let's just make sure this is done with interrupts disabled. It may be reasonable to handle this also somehow in PHY, but it needs more analysis and we don't want to break something. Also note that in other cases we set wfr so even if this happens, wfr will rescue us. --- nimble/controller/src/ble_ll_dtm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index d586b7112..0d6ab4aa6 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -358,6 +358,7 @@ schedule: static int ble_ll_dtm_rx_start(void) { + os_sr_t sr; int rc; rc = ble_phy_setchan(channel_rf_to_index[g_ble_ll_dtm_ctx.rf_channel], @@ -370,8 +371,10 @@ ble_ll_dtm_rx_start(void) ble_phy_mode_set(g_ble_ll_dtm_ctx.phy_mode, g_ble_ll_dtm_ctx.phy_mode); #endif + OS_ENTER_CRITICAL(sr); rc = ble_phy_rx_set_start_time(os_cputime_get32() + g_ble_ll_sched_offset_ticks, 0); + OS_EXIT_CRITICAL(sr); if (rc && rc != BLE_PHY_ERR_RX_LATE) { return rc; }