From 929dae8cad4bd7a84fb1132f3e314153f85de5db Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 28 Jan 2021 17:02:05 +0530 Subject: [PATCH] Bluetooth: controller: Add ISR cputime measurement Adding ISR cputime measurement for Radio, LLL, ULL_HIGH and ULL_LOW execution contexts. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/hci/hci.c | 8 ++- .../controller/ll_sw/nordic/lll/lll.c | 21 ++++++ .../controller/ll_sw/nordic/lll/lll_prof.c | 72 +++++++++++++++++++ .../ll_sw/nordic/lll/lll_prof_internal.h | 20 ++++++ subsys/bluetooth/controller/ll_sw/pdu.h | 4 ++ 5 files changed, 123 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index a82bb877ab9..82c77850689 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5731,13 +5731,17 @@ static void encode_control(struct node_rx_pdu *node_rx, #if defined(CONFIG_BT_CTLR_PROFILE_ISR) case NODE_RX_TYPE_PROFILE: - BT_INFO("l: %d, %d, %d; t: %d, %d, %d.", + BT_INFO("l: %u, %u, %u; t: %u, %u, %u; cpu: %u, %u, %u, %u.", pdu_data->profile.lcur, pdu_data->profile.lmin, pdu_data->profile.lmax, pdu_data->profile.cur, pdu_data->profile.min, - pdu_data->profile.max); + pdu_data->profile.max, + pdu_data->profile.radio, + pdu_data->profile.lll, + pdu_data->profile.ull_high, + pdu_data->profile.ull_low); return; #endif /* CONFIG_BT_CTLR_PROFILE_ISR */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 34aab347a8e..900d877f6a3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -30,6 +30,7 @@ #include "lll_vendor.h" #include "lll_clock.h" #include "lll_internal.h" +#include "lll_prof_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER) #define LOG_MODULE_NAME bt_ctlr_lll @@ -78,10 +79,14 @@ ISR_DIRECT_DECLARE(radio_nrf5_isr) { DEBUG_RADIO_ISR(1); + lll_prof_enter_radio(); + isr_radio(); ISR_DIRECT_PM(); + lll_prof_exit_radio(); + DEBUG_RADIO_ISR(0); return 1; } @@ -90,6 +95,8 @@ static void rtc0_nrf5_isr(const void *arg) { DEBUG_TICKER_ISR(1); + lll_prof_enter_ull_high(); + /* On compare0 run ticker worker instance0 */ if (NRF_RTC0->EVENTS_COMPARE[0]) { NRF_RTC0->EVENTS_COMPARE[0] = 0; @@ -99,9 +106,15 @@ static void rtc0_nrf5_isr(const void *arg) mayfly_run(TICKER_USER_ID_ULL_HIGH); + lll_prof_exit_ull_high(); + #if !defined(CONFIG_BT_CTLR_LOW_LAT) && \ (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) + lll_prof_enter_ull_low(); + mayfly_run(TICKER_USER_ID_ULL_LOW); + + lll_prof_exit_ull_low(); #endif DEBUG_TICKER_ISR(0); @@ -111,8 +124,12 @@ static void swi_lll_nrf5_isr(const void *arg) { DEBUG_RADIO_ISR(1); + lll_prof_enter_lll(); + mayfly_run(TICKER_USER_ID_LLL); + lll_prof_exit_lll(); + DEBUG_RADIO_ISR(0); } @@ -122,8 +139,12 @@ static void swi_ull_low_nrf5_isr(const void *arg) { DEBUG_TICKER_JOB(1); + lll_prof_enter_ull_low(); + mayfly_run(TICKER_USER_ID_ULL_LOW); + lll_prof_exit_ull_low(); + DEBUG_TICKER_JOB(0); } #endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c index b7f2f44ca88..984cccd83bd 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c @@ -18,6 +18,17 @@ #include "lll.h" +static inline void sample(uint32_t *timestamp); +static inline void delta(uint32_t timestamp, uint8_t *cputime); + +static uint32_t timestamp_radio; +static uint32_t timestamp_lll; +static uint32_t timestamp_ull_high; +static uint32_t timestamp_ull_low; +static uint8_t cputime_radio; +static uint8_t cputime_lll; +static uint8_t cputime_ull_high; +static uint8_t cputime_ull_low; static uint8_t latency_min = (uint8_t) -1; static uint8_t latency_max; static uint8_t latency_prev; @@ -26,6 +37,46 @@ static uint8_t cputime_max; static uint8_t cputime_prev; static uint32_t timestamp_latency; +void lll_prof_enter_radio(void) +{ + sample(×tamp_radio); +} + +void lll_prof_exit_radio(void) +{ + delta(timestamp_radio, &cputime_radio); +} + +void lll_prof_enter_lll(void) +{ + sample(×tamp_lll); +} + +void lll_prof_exit_lll(void) +{ + delta(timestamp_lll, &cputime_lll); +} + +void lll_prof_enter_ull_high(void) +{ + sample(×tamp_ull_high); +} + +void lll_prof_exit_ull_high(void) +{ + delta(timestamp_ull_high, &cputime_ull_high); +} + +void lll_prof_enter_ull_low(void) +{ + sample(×tamp_ull_low); +} + +void lll_prof_exit_ull_low(void) +{ + delta(timestamp_ull_low, &cputime_ull_low); +} + void lll_prof_latency_capture(void) { /* sample the packet timer, use it to calculate ISR latency @@ -134,9 +185,30 @@ void lll_prof_send(void) p->cur = cputime; p->min = cputime_min; p->max = cputime_max; + p->radio = cputime_radio; + p->lll = cputime_lll; + p->ull_high = cputime_ull_high; + p->ull_low = cputime_ull_low; ull_rx_put(rx->hdr.link, rx); ull_rx_sched(); } } } + +static inline void sample(uint32_t *timestamp) +{ + radio_tmr_sample(); + *timestamp = radio_tmr_sample_get(); +} + +static inline void delta(uint32_t timestamp, uint8_t *cputime) +{ + uint32_t delta; + + radio_tmr_sample(); + delta = radio_tmr_sample_get() - timestamp; + if (delta < UINT8_MAX && delta > *cputime) { + *cputime = delta; + } +} diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h index df4243894ea..8a318a9a601 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h @@ -4,6 +4,26 @@ * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_BT_CTLR_PROFILE_ISR) +void lll_prof_enter_radio(void); +void lll_prof_exit_radio(void); +void lll_prof_enter_lll(void); +void lll_prof_exit_lll(void); +void lll_prof_enter_ull_high(void); +void lll_prof_exit_ull_high(void); +void lll_prof_enter_ull_low(void); +void lll_prof_exit_ull_low(void); +#else +static inline void lll_prof_enter_radio(void) {} +static inline void lll_prof_exit_radio(void) {} +static inline void lll_prof_enter_lll(void) {} +static inline void lll_prof_exit_lll(void) {} +static inline void lll_prof_enter_ull_high(void) {} +static inline void lll_prof_exit_ull_high(void) {} +static inline void lll_prof_enter_ull_low(void) {} +static inline void lll_prof_exit_ull_low(void) {} +#endif + void lll_prof_latency_capture(void); void lll_prof_radio_end_backup(void); void lll_prof_cputime_capture(void); diff --git a/subsys/bluetooth/controller/ll_sw/pdu.h b/subsys/bluetooth/controller/ll_sw/pdu.h index 37dc230e720..0e7385ba85f 100644 --- a/subsys/bluetooth/controller/ll_sw/pdu.h +++ b/subsys/bluetooth/controller/ll_sw/pdu.h @@ -610,6 +610,10 @@ struct profile { uint8_t cur; uint8_t min; uint8_t max; + uint8_t radio; + uint8_t lll; + uint8_t ull_high; + uint8_t ull_low; } __packed; #endif /* CONFIG_BT_CTLR_PROFILE_ISR */