Bluetooth: controller: Framework for new feature BT_CTLR_JIT_SCHEDULING
This option enables BT_TICKER_SLOT_AGNOSTIC which eliminates priorities and collision resolving in the ticker. Event scheduling states are stored in the lll_hdr, and event priority is passed from LLL implementation, and runtime priority calculated. LLL implementation decides whether to program radio, start preemption timer, and/or queue prepare in the prepare pipeline. Event arbitration is made possible via the common LLL, but not yet implemented in Nordic LLL. Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
parent
9aaa120abd
commit
772a77718e
4 changed files with 66 additions and 1 deletions
|
@ -570,6 +570,15 @@ config BT_TICKER_SLOT_AGNOSTIC
|
||||||
reservations and collision handling, and operates as a simple
|
reservations and collision handling, and operates as a simple
|
||||||
multi-instance programmable timer.
|
multi-instance programmable timer.
|
||||||
|
|
||||||
|
config BT_CTLR_JIT_SCHEDULING
|
||||||
|
bool "Just-in-Time Scheduling"
|
||||||
|
select BT_TICKER_SLOT_AGNOSTIC
|
||||||
|
help
|
||||||
|
This option enables the experimental 'Next Generation' scheduling
|
||||||
|
feature, which eliminates priorities and collision resolving in the
|
||||||
|
ticker, and instead relies on just-in-time ("lazy") resolution in
|
||||||
|
the link layer.
|
||||||
|
|
||||||
config BT_CTLR_USER_EXT
|
config BT_CTLR_USER_EXT
|
||||||
prompt "Enable proprietary extensions in Controller"
|
prompt "Enable proprietary extensions in Controller"
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -160,12 +160,19 @@ struct ull_hdr {
|
||||||
|
|
||||||
struct lll_hdr {
|
struct lll_hdr {
|
||||||
void *parent;
|
void *parent;
|
||||||
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
uint8_t score;
|
||||||
|
uint8_t latency;
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lll_prepare_param {
|
struct lll_prepare_param {
|
||||||
uint32_t ticks_at_expire;
|
uint32_t ticks_at_expire;
|
||||||
uint32_t remainder;
|
uint32_t remainder;
|
||||||
uint16_t lazy;
|
uint16_t lazy;
|
||||||
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
int8_t prio;
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
uint8_t force;
|
uint8_t force;
|
||||||
void *param;
|
void *param;
|
||||||
};
|
};
|
||||||
|
@ -379,8 +386,15 @@ static inline void lll_hdr_init(void *lll, void *parent)
|
||||||
struct lll_hdr *hdr = lll;
|
struct lll_hdr *hdr = lll;
|
||||||
|
|
||||||
hdr->parent = parent;
|
hdr->parent = parent;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
hdr->score = 0U;
|
||||||
|
hdr->latency = 0U;
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted);
|
||||||
|
|
||||||
int lll_init(void);
|
int lll_init(void);
|
||||||
int lll_reset(void);
|
int lll_reset(void);
|
||||||
void lll_resume(void *param);
|
void lll_resume(void *param);
|
||||||
|
|
|
@ -41,7 +41,27 @@ int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
|
||||||
lll_prepare_cb_t prepare_cb, int8_t event_prio,
|
lll_prepare_cb_t prepare_cb, int8_t event_prio,
|
||||||
struct lll_prepare_param *prepare_param)
|
struct lll_prepare_param *prepare_param)
|
||||||
{
|
{
|
||||||
/* TODO: Calculate priority */
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
int prio = event_prio;
|
||||||
|
struct lll_hdr *hdr = prepare_param->param;
|
||||||
|
|
||||||
|
/* Establish priority based on:
|
||||||
|
* 1. Event priority passed to function
|
||||||
|
* 2. Force flag => priority = -127
|
||||||
|
* 3. Score (events terminated- and too late)
|
||||||
|
* 4. Latency (skipped- and programmed latency)
|
||||||
|
* 5. Critical priority is immutable (-128)
|
||||||
|
*/
|
||||||
|
if (prio > -128) {
|
||||||
|
if (prepare_param->force) {
|
||||||
|
prio = -127;
|
||||||
|
} else {
|
||||||
|
prio = MAX(-127, prio - hdr->score - hdr->latency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_param->prio = prio;
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
|
|
||||||
return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb,
|
return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb,
|
||||||
prepare_param, 0, 0);
|
prepare_param, 0, 0);
|
||||||
|
@ -58,3 +78,21 @@ void lll_resume(void *param)
|
||||||
next->is_resume, 1);
|
next->is_resume, 1);
|
||||||
LL_ASSERT(!ret || ret == -EINPROGRESS);
|
LL_ASSERT(!ret || ret == -EINPROGRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
void lll_done_score(void *param, uint8_t too_late, uint8_t aborted)
|
||||||
|
{
|
||||||
|
struct lll_hdr *hdr = param;
|
||||||
|
|
||||||
|
if (!hdr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!too_late && !aborted) {
|
||||||
|
hdr->score = 0;
|
||||||
|
hdr->latency = 0;
|
||||||
|
} else {
|
||||||
|
hdr->score++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
|
|
|
@ -344,6 +344,10 @@ int lll_done(void *param)
|
||||||
ull_prepare_dequeue(TICKER_USER_ID_LLL);
|
ull_prepare_dequeue(TICKER_USER_ID_LLL);
|
||||||
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
|
#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL_DONE */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
|
||||||
|
lll_done_score(param, 0, 0); /* TODO */
|
||||||
|
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
|
||||||
|
|
||||||
/* Let ULL know about LLL event done */
|
/* Let ULL know about LLL event done */
|
||||||
evdone = ull_event_done(ull);
|
evdone = ull_event_done(ull);
|
||||||
LL_ASSERT(evdone);
|
LL_ASSERT(evdone);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue