Skip to content

Commit fdc92eb

Browse files
mtpr-otcfriedt
authored andcommitted
Bluetooth: controller: Implement ADV re-schedule for new scheduler
The new JIT scheduler does not have slot reservation, which means that the ticker extension feature for automatically re-scheduling a colliding non-anchored event, e.g. ADV, cannot be used. This implementaion reacts to ADV envent done with result ABORTED or TOO_LATE, and in those cases attempts to re-schedule the ADV event again within the 10 ms pertubation window. As the original scheduling, the re-scheduling is randomized, so there is no absolute predictability as to how many attempts will be made. The advertiser will attempt with randomly delayed re-schdules until the window is exhausted. If re-scheduling is unsuccessful, the weight of the ADV event is increased, improving it's chances of success in the next event. Signed-off-by: Morten Priess <[email protected]>
1 parent 7ade4a2 commit fdc92eb

File tree

8 files changed

+159
-35
lines changed

8 files changed

+159
-35
lines changed

subsys/bluetooth/controller/ll_sw/lll.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ enum {
134134

135135
#define TICKER_ID_ULL_BASE ((TICKER_ID_LLL_PREEMPT) + 1)
136136

137+
enum done_result {
138+
DONE_COMPLETED,
139+
DONE_ABORTED,
140+
DONE_LATE
141+
};
142+
137143
struct ull_hdr {
138144
uint8_t volatile ref; /* Number of ongoing (between Prepare and Done)
139145
* events
@@ -331,11 +337,11 @@ enum {
331337
EVENT_DONE_EXTRA_TYPE_CONN,
332338
#endif /* CONFIG_BT_CONN */
333339

334-
#if defined(CONFIG_BT_CTLR_ADV_EXT)
340+
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
335341
#if defined(CONFIG_BT_BROADCASTER)
336342
EVENT_DONE_EXTRA_TYPE_ADV,
337343
#endif /* CONFIG_BT_BROADCASTER */
338-
#endif /* CONFIG_BT_CTLR_ADV_EXT */
344+
#endif /* CONFIG_BT_CTLR_ADV_EXT || CONFIG_BT_CTLR_JIT_SCHEDULING */
339345

340346
#if defined(CONFIG_BT_OBSERVER)
341347
#if defined(CONFIG_BT_CTLR_ADV_EXT)
@@ -368,6 +374,9 @@ struct event_done_extra_drift {
368374

369375
struct event_done_extra {
370376
uint8_t type;
377+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
378+
uint8_t result;
379+
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
371380
union {
372381
struct {
373382
uint16_t trx_cnt;
@@ -402,7 +411,7 @@ static inline void lll_hdr_init(void *lll, void *parent)
402411
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
403412
}
404413

405-
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted);
414+
void lll_done_score(void *param, uint8_t result);
406415

407416
int lll_init(void);
408417
int lll_reset(void);

subsys/bluetooth/controller/ll_sw/lll_common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ void lll_resume(void *param)
8080
}
8181

8282
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
83-
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted)
83+
void lll_done_score(void *param, uint8_t result)
8484
{
8585
struct lll_hdr *hdr = param;
8686

8787
if (!hdr) {
8888
return;
8989
}
9090

91-
if (!too_late && !aborted) {
91+
if (result == DONE_COMPLETED) {
9292
hdr->score = 0;
9393
hdr->latency = 0;
9494
} else {

subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,19 @@ int lll_done(void *param)
344344
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
345345

346346
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
347-
lll_done_score(param, 0, 0); /* TODO */
347+
struct event_done_extra *extra;
348+
uint8_t result;
349+
350+
/* TODO: Pass from calling function */
351+
result = DONE_COMPLETED;
352+
353+
lll_done_score(param, result);
354+
355+
extra = ull_event_done_extra_get();
356+
LL_ASSERT(extra);
357+
358+
/* Set result in done extra data - type was set by the role */
359+
extra->result = result;
348360
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
349361

350362
/* Let ULL know about LLL event done */

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "lll_prof_internal.h"
4646
#include "lll_df_internal.h"
4747

48+
#include "ull_internal.h"
49+
4850
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
4951
#define LOG_MODULE_NAME bt_ctlr_lll_adv
5052
#include "common/log.h"
@@ -1209,14 +1211,9 @@ static void isr_done(void *param)
12091211
}
12101212
#endif /* CONFIG_BT_CTLR_ADV_INDICATION */
12111213

1212-
#if defined(CONFIG_BT_CTLR_ADV_EXT)
1213-
struct event_done_extra *extra;
1214-
1215-
extra = ull_event_done_extra_get();
1216-
LL_ASSERT(extra);
1217-
1218-
extra->type = EVENT_DONE_EXTRA_TYPE_ADV;
1219-
#endif /* CONFIG_BT_CTLR_ADV_EXT */
1214+
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
1215+
ull_done_extra_type_set(EVENT_DONE_EXTRA_TYPE_ADV);
1216+
#endif /* CONFIG_BT_CTLR_ADV_EXT || CONFIG_BT_CTLR_JIT_SCHEDULING */
12201217

12211218
lll_isr_cleanup(param);
12221219
}

subsys/bluetooth/controller/ll_sw/ull.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2484,13 +2484,16 @@ static inline void rx_demux_event_done(memq_link_t *link,
24842484
break;
24852485
#endif /* CONFIG_BT_CONN */
24862486

2487-
#if defined(CONFIG_BT_CTLR_ADV_EXT)
24882487
#if defined(CONFIG_BT_BROADCASTER)
2488+
#if defined(CONFIG_BT_CTLR_ADV_EXT) || \
2489+
defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
24892490
case EVENT_DONE_EXTRA_TYPE_ADV:
24902491
ull_adv_done(done);
24912492
break;
2493+
#endif /* CONFIG_BT_CTLR_ADV_EXT || CONFIG_BT_CTLR_JIT_SCHEDULING */
24922494
#endif /* CONFIG_BT_BROADCASTER */
24932495

2496+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
24942497
#if defined(CONFIG_BT_OBSERVER)
24952498
case EVENT_DONE_EXTRA_TYPE_SCAN:
24962499
ull_scan_done(done);
@@ -2553,3 +2556,15 @@ static void disabled_cb(void *param)
25532556
{
25542557
k_sem_give(param);
25552558
}
2559+
2560+
struct event_done_extra *ull_done_extra_type_set(uint8_t type)
2561+
{
2562+
struct event_done_extra *extra;
2563+
2564+
extra = ull_event_done_extra_get();
2565+
LL_ASSERT(extra);
2566+
2567+
extra->type = type;
2568+
2569+
return extra;
2570+
}

subsys/bluetooth/controller/ll_sw/ull_adv.c

Lines changed: 105 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "hal/ccm.h"
1717
#include "hal/radio.h"
1818
#include "hal/ticker.h"
19+
#include "hal/cntr.h"
1920

2021
#include "util/util.h"
2122
#include "util/mem.h"
@@ -1732,20 +1733,109 @@ uint8_t ull_scan_rsp_set(struct ll_adv_set *adv, uint8_t len,
17321733
return 0;
17331734
}
17341735

1735-
#if defined(CONFIG_BT_CTLR_ADV_EXT)
1736+
static uint32_t ticker_update_rand(struct ll_adv_set *adv, uint32_t ticks_delay_window,
1737+
uint32_t ticks_delay_window_offset,
1738+
uint32_t ticks_adjust_minus)
1739+
{
1740+
uint32_t random_delay;
1741+
uint32_t ret;
1742+
1743+
/* Get pseudo-random number in the range [0..ticks_delay_window].
1744+
* Please note that using modulo of 2^32 samle space has an uneven
1745+
* distribution, slightly favoring smaller values.
1746+
*/
1747+
lll_rand_isr_get(&random_delay, sizeof(random_delay));
1748+
random_delay %= ticks_delay_window;
1749+
random_delay += (ticks_delay_window_offset + 1);
1750+
1751+
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
1752+
TICKER_USER_ID_ULL_HIGH,
1753+
TICKER_ID_ADV_BASE + ull_adv_handle_get(adv),
1754+
random_delay,
1755+
ticks_adjust_minus, 0, 0, 0, 0,
1756+
ticker_op_update_cb, adv);
1757+
1758+
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
1759+
(ret == TICKER_STATUS_BUSY));
1760+
1761+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
1762+
adv->delay = random_delay;
1763+
#endif
1764+
return random_delay;
1765+
}
1766+
1767+
#if defined(CONFIG_BT_CTLR_ADV_EXT) || \
1768+
defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
17361769
void ull_adv_done(struct node_rx_event_done *done)
17371770
{
1771+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
17381772
struct lll_adv_aux *lll_aux;
17391773
struct node_rx_hdr *rx_hdr;
1740-
struct ll_adv_set *adv;
1741-
struct lll_adv *lll;
17421774
uint8_t handle;
17431775
uint32_t ret;
1776+
#endif /* CONFIG_BT_CTLR_ADV_EXT */
1777+
struct ll_adv_set *adv;
1778+
struct lll_adv *lll;
17441779

17451780
/* Get reference to ULL context */
17461781
adv = CONTAINER_OF(done->param, struct ll_adv_set, ull);
17471782
lll = &adv->lll;
17481783

1784+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
1785+
if (done->extra.result == DONE_COMPLETED) {
1786+
/* Event completed successfully */
1787+
adv->delay_remain = ULL_ADV_RANDOM_DELAY;
1788+
} else {
1789+
/* Event aborted or too late - try to re-schedule */
1790+
uint32_t ticks_elapsed;
1791+
uint32_t ticks_now;
1792+
1793+
const uint32_t prepare_overhead =
1794+
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
1795+
const uint32_t ticks_adv_airtime = adv->ticks_at_expire +
1796+
prepare_overhead;
1797+
1798+
ticks_elapsed = 0;
1799+
1800+
ticks_now = cntr_cnt_get();
1801+
if ((int32_t)(ticks_now - ticks_adv_airtime) > 0) {
1802+
ticks_elapsed = ticks_now - ticks_adv_airtime;
1803+
}
1804+
1805+
if (adv->delay_remain >= adv->delay + ticks_elapsed) {
1806+
/* The perturbation window is still open */
1807+
adv->delay_remain -= (adv->delay + ticks_elapsed);
1808+
} else {
1809+
adv->delay_remain = 0;
1810+
}
1811+
1812+
/* Check if we have enough time to re-schedule */
1813+
if (adv->delay_remain > prepare_overhead) {
1814+
uint32_t ticks_adjust_minus;
1815+
1816+
/* Get negative ticker adjustment needed to pull back ADV one
1817+
* interval plus the randomized delay. This means that the ticker
1818+
* will be updated to expire in time frame of now + start
1819+
* overhead, until 10 ms window is exhausted.
1820+
*/
1821+
ticks_adjust_minus = HAL_TICKER_US_TO_TICKS(
1822+
(uint64_t)adv->interval * ADV_INT_UNIT_US) + adv->delay;
1823+
1824+
/* Apply random delay in range [prepare_overhead..delay_remain] */
1825+
ticker_update_rand(adv, adv->delay_remain - prepare_overhead,
1826+
prepare_overhead, ticks_adjust_minus);
1827+
1828+
/* Score of the event was increased due to the result, but since
1829+
* we're getting a another chance we'll set it back.
1830+
*/
1831+
adv->lll.hdr.score -= 1;
1832+
} else {
1833+
adv->delay_remain = ULL_ADV_RANDOM_DELAY;
1834+
}
1835+
}
1836+
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
1837+
1838+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
17491839
if (adv->max_events && (adv->event_counter >= adv->max_events)) {
17501840
adv->max_events = 0;
17511841

@@ -1791,8 +1881,9 @@ void ull_adv_done(struct node_rx_event_done *done)
17911881

17921882
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
17931883
(ret == TICKER_STATUS_BUSY));
1794-
}
17951884
#endif /* CONFIG_BT_CTLR_ADV_EXT */
1885+
}
1886+
#endif /* CONFIG_BT_CTLR_ADV_EXT || CONFIG_BT_CTLR_JIT_SCHEDULING */
17961887

17971888
const uint8_t *ull_adv_pdu_update_addrs(struct ll_adv_set *adv,
17981889
struct pdu_adv *pdu)
@@ -1971,6 +2062,7 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t laz
19712062
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_prepare};
19722063
static struct lll_prepare_param p;
19732064
struct ll_adv_set *adv = param;
2065+
uint32_t random_delay;
19742066
struct lll_adv *lll;
19752067
uint32_t ret;
19762068
uint8_t ref;
@@ -1997,29 +2089,19 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t laz
19972089
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
19982090
TICKER_USER_ID_LLL, 0, &mfy);
19992091
LL_ASSERT(!ret);
2092+
2093+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
2094+
adv->ticks_at_expire = ticks_at_expire;
2095+
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
20002096
}
20012097

20022098
/* Apply adv random delay */
20032099
#if defined(CONFIG_BT_PERIPHERAL)
20042100
if (!lll->is_hdcd)
20052101
#endif /* CONFIG_BT_PERIPHERAL */
20062102
{
2007-
uint32_t random_delay;
2008-
uint32_t ret;
2009-
2010-
lll_rand_isr_get(&random_delay, sizeof(random_delay));
2011-
random_delay %= ULL_ADV_RANDOM_DELAY;
2012-
random_delay += 1;
2013-
2014-
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
2015-
TICKER_USER_ID_ULL_HIGH,
2016-
(TICKER_ID_ADV_BASE +
2017-
ull_adv_handle_get(adv)),
2018-
random_delay,
2019-
0, 0, 0, 0, 0,
2020-
ticker_op_update_cb, adv);
2021-
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
2022-
(ret == TICKER_STATUS_BUSY));
2103+
/* Apply random delay in range [0..ULL_ADV_RANDOM_DELAY] */
2104+
random_delay = ticker_update_rand(adv, ULL_ADV_RANDOM_DELAY, 0, 0);
20232105

20242106
#if defined(CONFIG_BT_CTLR_ADV_EXT)
20252107
adv->event_counter += (lazy + 1);
@@ -2581,6 +2663,9 @@ static void init_set(struct ll_adv_set *adv)
25812663
#endif /* CONFIG_BT_CTLR_PRIVACY */
25822664
adv->lll.chan_map = BT_LE_ADV_CHAN_MAP_ALL;
25832665
adv->lll.filter_policy = BT_LE_ADV_FP_NO_WHITELIST;
2666+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
2667+
adv->delay_remain = ULL_ADV_RANDOM_DELAY;
2668+
#endif /* ONFIG_BT_CTLR_JIT_SCHEDULING */
25842669

25852670
init_pdu(lll_adv_data_peek(&ll_adv[0].lll), PDU_ADV_TYPE_ADV_IND);
25862671
init_pdu(lll_adv_scan_rsp_peek(&ll_adv[0].lll), PDU_ADV_TYPE_SCAN_RSP);

subsys/bluetooth/controller/ll_sw/ull_adv_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ struct ll_adv_set {
5757
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
5858
struct lll_df_adv_cfg *df_cfg;
5959
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
60+
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
61+
uint32_t delay;
62+
uint32_t delay_remain;
63+
uint32_t ticks_at_expire;
64+
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
6065
};
6166

6267
#if defined(CONFIG_BT_CTLR_ADV_EXT)

subsys/bluetooth/controller/ll_sw/ull_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ int ull_disable(void *param);
5353
void ull_drift_ticks_get(struct node_rx_event_done *done,
5454
uint32_t *ticks_drift_plus,
5555
uint32_t *ticks_drift_minus);
56+
struct event_done_extra *ull_done_extra_type_set(uint8_t type);

0 commit comments

Comments
 (0)