Bluetooth: Controller: Propagate ticks_drift in the ticker callback

The ticker `ticks_drift` is propagated via the ticker
elapsed callback, in order to provide necessary information
to correctly calculate total elapsed durations by states and
roles that use ticker extensions to mitigate scheduling
collisions by drifting within a permitted window.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-09-15 11:48:21 +05:30 committed by Carles Cufí
parent b01b5f6786
commit 19fe102862
21 changed files with 121 additions and 71 deletions

View File

@ -52,6 +52,7 @@ static inline int _ticker_stop(uint8_t inst_idx, uint8_t u_id, uint8_t tic_id)
}
static void time_slot_callback_work(uint32_t ticks_at_expire,
uint32_t ticks_drift,
uint32_t remainder,
uint16_t lazy, uint8_t force,
void *context)
@ -120,6 +121,7 @@ static void time_slot_delay(uint32_t ticks_at_expire, uint32_t ticks_delay,
}
static void time_slot_callback_abort(uint32_t ticks_at_expire,
uint32_t ticks_drift,
uint32_t remainder,
uint16_t lazy, uint8_t force,
void *context)
@ -132,13 +134,14 @@ static void time_slot_callback_abort(uint32_t ticks_at_expire,
}
static void time_slot_callback_prepare(uint32_t ticks_at_expire,
uint32_t ticks_drift,
uint32_t remainder,
uint16_t lazy, uint8_t force,
void *context)
{
#if defined(CONFIG_BT_CTLR_LOW_LAT)
time_slot_callback_abort(ticks_at_expire, remainder, lazy, force,
context);
time_slot_callback_abort(ticks_at_expire, ticks_drift, remainder, lazy,
force, context);
#else /* !CONFIG_BT_CTLR_LOW_LAT */
time_slot_delay(ticks_at_expire,
HAL_TICKER_US_TO_TICKS(FLASH_RADIO_ABORT_DELAY_US),

View File

@ -72,8 +72,9 @@ static void isr_race(void *param);
static uint32_t preempt_ticker_start(struct lll_event *prev,
struct lll_event *next);
static uint32_t preempt_ticker_stop(void);
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void preempt(void *param);
#else /* CONFIG_BT_CTLR_LOW_LAT */
#if (CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO)
@ -857,8 +858,9 @@ static uint32_t preempt_ticker_stop(void)
return ret;
}
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, preempt};

View File

@ -54,8 +54,9 @@ static int common_prepare_cb(struct lll_prepare_param *p, bool is_resume);
static int is_abort_cb(void *next, void *curr,
lll_prepare_cb_t *resume_cb);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_start_cb(uint32_t status, void *param);
static void isr_rx(void *param);
static void isr_tx(void *param);
@ -593,8 +594,8 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
lll_done(param);
}
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param)
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force, void *param)
{
radio_isr_set(isr_done_cleanup, param);
radio_disable();

View File

@ -66,8 +66,9 @@ static void ticker_start_op_cb(uint32_t status, void *param);
static void ticker_start_next_op_cb(uint32_t status, void *param);
static uint32_t preempt_ticker_start(struct lll_event *event,
ticker_op_func op_cb);
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void preempt(void *param);
#else /* CONFIG_BT_CTLR_LOW_LAT */
#if (CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO)
@ -670,8 +671,9 @@ static uint32_t preempt_ticker_start(struct lll_event *event,
return ret;
}
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void preempt_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, preempt};

View File

@ -43,8 +43,9 @@ static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *prepare_param);
static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_start_cb(uint32_t status, void *param);
static void isr_rx(void *param);
static void isr_tx(void *param);
@ -329,8 +330,9 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
lll_done(param);
}
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param)
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
radio_isr_set(isr_cleanup, param);
radio_disable();

View File

@ -66,13 +66,15 @@ static uint16_t adv_time_get(struct pdu_adv *pdu, struct pdu_adv *pdu_scan,
uint8_t adv_chn_cnt, uint8_t phy,
uint8_t phy_flags);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_update_op_cb(uint32_t status, void *param);
#if defined(CONFIG_BT_PERIPHERAL)
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_stop_op_cb(uint32_t status, void *param);
static void adv_disable(void *param);
static void disabled_cb(void *param);
@ -2093,8 +2095,9 @@ static uint16_t adv_time_get(struct pdu_adv *pdu, struct pdu_adv *pdu_scan,
return time_us;
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_prepare};
@ -2180,8 +2183,9 @@ static void ticker_update_op_cb(uint32_t status, void *param)
}
#if defined(CONFIG_BT_PERIPHERAL)
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
struct ll_adv_set *adv = param;
uint8_t handle;

View File

@ -51,8 +51,9 @@ static uint16_t aux_time_get(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
struct pdu_adv *pdu_scan);
static void mfy_aux_offset_get(void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_cb(uint32_t status, void *param);
static struct ll_adv_aux_set ll_adv_aux_pool[CONFIG_BT_CTLR_ADV_AUX_SET];
@ -1269,8 +1270,9 @@ static void mfy_aux_offset_get(void *param)
ull_adv_aux_lll_offset_fill(ticks_to_expire, 0, pdu);
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_aux_prepare};

View File

@ -47,8 +47,9 @@ static uint32_t ull_adv_iso_start(struct ll_adv_iso *adv_iso,
uint32_t ticks_anchor);
static inline struct ll_adv_iso *ull_adv_iso_get(uint8_t handle);
static int init_reset(void);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void tx_lll_flush(void *param);
static void ticker_op_stop_cb(uint32_t status, void *param);
@ -424,8 +425,9 @@ static int init_reset(void)
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
/* TODO: LLL support for ADV ISO */
#if 0

View File

@ -59,8 +59,9 @@ static inline struct pdu_adv_sync_info *sync_info_get(struct pdu_adv *pdu);
static inline void sync_info_offset_fill(struct pdu_adv_sync_info *si,
uint32_t ticks_offset,
uint32_t start_us);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_cb(uint32_t status, void *param);
static struct ll_adv_sync_set ll_adv_sync_pool[CONFIG_BT_CTLR_ADV_SYNC_SET];
@ -1616,8 +1617,9 @@ static inline void sync_info_offset_fill(struct pdu_adv_sync_info *si,
}
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_sync_prepare};

View File

@ -311,8 +311,9 @@ static void ticker_resume_op_cb(uint32_t status, void *param)
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
}
static void ticker_resume_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_resume_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_resume};

View File

@ -902,8 +902,9 @@ void ull_master_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
#endif
}
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_master_prepare};

View File

@ -7,6 +7,7 @@
void ull_master_cleanup(struct node_rx_hdr *rx_free);
void ull_master_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll);
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
uint8_t ull_master_chm_update(void);

View File

@ -185,8 +185,9 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind,
return 0;
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = { 0, 0, &link, NULL,

View File

@ -50,8 +50,9 @@
#include "hal/debug.h"
static int init_reset(void);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static uint8_t disable(uint8_t handle);
#if defined(CONFIG_BT_CTLR_ADV_EXT)
@ -655,8 +656,9 @@ static int init_reset(void)
return 0;
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_scan_prepare};

View File

@ -47,8 +47,9 @@ static inline struct ll_sync_set *sync_create_get(struct ll_scan_set *scan);
static void last_disabled_cb(void *param);
static void done_disabled_cb(void *param);
static void flush(struct ll_scan_aux_set *aux);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_cb(uint32_t status, void *param);
static void ticker_op_aux_failure(void *param);
@ -772,8 +773,9 @@ static void flush(struct ll_scan_aux_set *aux)
aux_release(aux);
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_scan_aux_prepare};

View File

@ -456,8 +456,9 @@ void ull_slave_latency_cancel(struct ll_conn *conn, uint16_t handle)
}
}
void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_slave_prepare};

View File

@ -7,5 +7,6 @@
void ull_slave_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll);
void ull_slave_latency_cancel(struct ll_conn *conn, uint16_t handle);
void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);

View File

@ -50,8 +50,9 @@
static int init_reset(void);
static inline struct ll_sync_set *sync_acquire(void);
static void timeout_cleanup(struct ll_sync_set *sync);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_cb(uint32_t status, void *param);
static void ticker_update_sync_op_cb(uint32_t status, void *param);
static void ticker_stop_op_cb(uint32_t status, void *param);
@ -759,8 +760,9 @@ static void timeout_cleanup(struct ll_sync_set *sync)
(ret == TICKER_STATUS_BUSY));
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, lll_sync_prepare};

View File

@ -45,8 +45,9 @@
static int init_reset(void);
static inline struct ll_sync_iso *sync_iso_acquire(void);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param);
static void ticker_op_cb(uint32_t status, void *param);
static struct ll_sync_iso ll_sync_iso_pool[CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET];
@ -306,8 +307,9 @@ static inline struct ll_sync_iso *sync_iso_acquire(void)
return mem_acquire(&sync_iso_free);
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param)
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
uint32_t remainder, uint16_t lazy, uint8_t force,
void *param)
{
/* TODO: Implement LLL handling */
#if 0

View File

@ -892,6 +892,7 @@ void ticker_worker(void *param)
struct ticker_node *ticker;
uint32_t ticks_to_expire;
uint8_t must_expire_skip;
uint32_t ticks_drift;
ticker = &node[ticker_id_head];
@ -960,14 +961,25 @@ void ticker_worker(void *param)
#if defined(CONFIG_BT_TICKER_EXT)
if (ticker->ext_data) {
ticks_drift = ticker->ext_data->ticks_drift;
ticker->ext_data->ticks_drift = 0U;
/* Mark node as not re-scheduling */
ticker->ext_data->reschedule_state =
TICKER_RESCHEDULE_STATE_NONE;
} else {
ticks_drift = 0U;
}
#endif /* CONFIG_BT_TICKER_EXT */
#endif /* !CONFIG_BT_TICKER_LOW_LAT &&
* !CONFIG_BT_TICKER_SLOT_AGNOSTIC
#else /* !CONFIG_BT_TICKER_EXT */
ticks_drift = 0U;
#endif /* !CONFIG_BT_TICKER_EXT */
#else /* CONFIG_BT_TICKER_LOW_LAT ||
* CONFIG_BT_TICKER_SLOT_AGNOSTIC
*/
ticks_drift = 0U;
#endif /* CONFIG_BT_TICKER_LOW_LAT ||
* CONFIG_BT_TICKER_SLOT_AGNOSTIC
*/
/* Scheduled timeout is acknowledged to be complete */
ticker->ack--;
@ -983,6 +995,7 @@ void ticker_worker(void *param)
DEBUG_TICKER_TASK(1);
/* Invoke the timeout callback */
ticker->timeout_func(ticks_at_expire,
ticks_drift,
ticker->remainder_current,
must_expire_skip ?
TICKER_LAZY_MUST_EXPIRE :
@ -1922,6 +1935,8 @@ static uint8_t ticker_job_reschedule_in_window(struct ticker_instance *instance,
ticker_id_iter = node->next;
}
ticker->ext_data->ticks_drift += ticks_to_expire -
ticker->ticks_to_expire;
ticker->ticks_to_expire = ticks_to_expire;
ticker_id_iter = nodes[ticker_id_head].next;
ticker_id_prev = TICKER_NULL;

View File

@ -97,8 +97,9 @@ typedef void (*ticker_trigger_set_cb_t)(uint32_t value);
/** \brief Timer timeout function type.
*/
typedef void (*ticker_timeout_func) (uint32_t ticks_at_expire,
uint32_t remainder, uint16_t lazy,
uint8_t force, void *context);
uint32_t ticks_drift, uint32_t remainder,
uint16_t lazy, uint8_t force,
void *context);
/** \brief Timer operation complete function type.
*/