Bluetooth: controller: Make must-expire runtime configurable

Under CONFIG_BT_TICKER_EXT configuration, the ticker interface has been
extended to support enabling/disabling must-expire scheduling. This
means that conn and slave ticker start calls can now omit must-expire
default-on configuration, relying on LLL updating the mode as needed.

Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
Morten Priess 2020-12-07 11:16:25 +01:00 committed by Carles Cufí
commit 467fd155a8
4 changed files with 71 additions and 19 deletions

View file

@ -2474,11 +2474,11 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy,
ticks_at_expire, ticks_win_offset,
HAL_TICKER_US_TO_TICKS(periodic_us),
HAL_TICKER_REMAINDER(periodic_us),
#if defined(CONFIG_BT_CTLR_CONN_META)
TICKER_LAZY_MUST_EXPIRE,
#else
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
TICKER_NULL_LAZY,
#endif /* CONFIG_BT_CTLR_CONN_META */
#else
TICKER_LAZY_MUST_EXPIRE_KEEP,
#endif
(ticks_slot_overhead +
conn->evt.ticks_slot),
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CENTRAL)

View file

@ -356,11 +356,7 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
HAL_TICKER_US_TO_TICKS(conn_offset_us),
HAL_TICKER_US_TO_TICKS(conn_interval_us),
HAL_TICKER_REMAINDER(conn_interval_us),
#if defined(CONFIG_BT_CTLR_CONN_META)
TICKER_LAZY_MUST_EXPIRE,
#else
TICKER_NULL_LAZY,
#endif /* CONFIG_BT_CTLR_CONN_META */
(conn->evt.ticks_slot +
ticks_slot_overhead),
ull_slave_ticker_cb, conn, ticker_op_cb,

View file

@ -146,6 +146,14 @@ struct ticker_user_op_update {
* >1: latency = lazy - 1
*/
uint8_t force; /* Force update */
#if defined(CONFIG_BT_TICKER_EXT)
uint8_t must_expire; /* Node must expire, even if it
* collides with other nodes:
* 0x00: Do nothing
* 0x01: Disable must_expire
* 0x02: Enable must_expire
*/
#endif
};
/* User operation data structure for stop opcode. Used for passing stop
@ -1157,6 +1165,14 @@ static inline void ticker_job_node_update(struct ticker_node *ticker,
ticker->force = user_op->params.update.force;
}
#if defined(CONFIG_BT_TICKER_EXT)
/* Update must_expire parameter */
if (user_op->params.update.must_expire) {
/* 1: disable, 2: enable */
ticker->must_expire = (user_op->params.update.must_expire - 1);
}
#endif /* CONFIG_BT_TICKER_EXT */
ticker->next = *insert_head;
*insert_head = user_op->id;
}
@ -1575,10 +1591,13 @@ static inline void ticker_job_op_start(struct ticker_node *ticker,
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
/* Must expire is not supported in compatibility mode */
LL_ASSERT(start->lazy != TICKER_LAZY_MUST_EXPIRE);
LL_ASSERT(start->lazy < TICKER_LAZY_MUST_EXPIRE_KEEP);
#else
ticker->must_expire = (start->lazy == TICKER_LAZY_MUST_EXPIRE) ? 1U :
0U;
if (start->lazy != TICKER_LAZY_MUST_EXPIRE_KEEP) {
/* Update the must_expire state */
ticker->must_expire =
(start->lazy == TICKER_LAZY_MUST_EXPIRE) ? 1U : 0U;
}
#if defined(CONFIG_BT_TICKER_EXT)
ticker->ext_data = start->ext_data;
#endif /* CONFIG_BT_TICKER_EXT */
@ -1586,8 +1605,9 @@ static inline void ticker_job_op_start(struct ticker_node *ticker,
ticker->ticks_periodic = start->ticks_periodic;
ticker->remainder_periodic = start->remainder_periodic;
ticker->lazy_periodic = (start->lazy == TICKER_LAZY_MUST_EXPIRE) ? 0U :
start->lazy;
ticker->lazy_periodic =
(start->lazy < TICKER_LAZY_MUST_EXPIRE_KEEP) ? start->lazy :
0U;
ticker->ticks_slot = start->ticks_slot;
ticker->timeout_func = start->fp_timeout_func;
ticker->context = start->context;
@ -2597,16 +2617,36 @@ uint32_t ticker_start(uint8_t instance_index, uint8_t user_id, uint8_t ticker_id
* @param fp_op_func Function pointer of user operation completion
* function
* @param op_context Context passed in operation completion call
* @param must_expire Disable, enable or ignore the must-expire state.
* A value of 0 means no change, 1 means disable and
* 2 means enable.
*
* @return TICKER_STATUS_BUSY if update was successful but not yet completed.
* TICKER_STATUS_FAILURE is returned if there are no more user operations
* available, and TICKER_STATUS_SUCCESS is returned if ticker_job gets to run
* before exiting ticker_update
*/
uint32_t ticker_update(uint8_t instance_index, uint8_t user_id, uint8_t ticker_id,
uint32_t ticks_drift_plus, uint32_t ticks_drift_minus,
uint32_t ticks_slot_plus, uint32_t ticks_slot_minus, uint16_t lazy,
uint8_t force, ticker_op_func fp_op_func, void *op_context)
uint32_t ticker_update(uint8_t instance_index, uint8_t user_id,
uint8_t ticker_id, uint32_t ticks_drift_plus,
uint32_t ticks_drift_minus, uint32_t ticks_slot_plus,
uint32_t ticks_slot_minus, uint16_t lazy, uint8_t force,
ticker_op_func fp_op_func, void *op_context)
#if defined(CONFIG_BT_TICKER_EXT)
{
return ticker_update_ext(instance_index, user_id, ticker_id,
ticks_drift_plus, ticks_drift_minus,
ticks_slot_plus, ticks_slot_minus, lazy,
force, fp_op_func, op_context, 0);
}
uint32_t ticker_update_ext(uint8_t instance_index, uint8_t user_id,
uint8_t ticker_id, uint32_t ticks_drift_plus,
uint32_t ticks_drift_minus,
uint32_t ticks_slot_plus, uint32_t ticks_slot_minus,
uint16_t lazy, uint8_t force,
ticker_op_func fp_op_func, void *op_context,
uint8_t must_expire)
#endif /* CONFIG_BT_TICKER_EXT */
{
struct ticker_instance *instance = &_instance[instance_index];
struct ticker_user_op *user_op;
@ -2633,6 +2673,9 @@ uint32_t ticker_update(uint8_t instance_index, uint8_t user_id, uint8_t ticker_i
user_op->params.update.ticks_slot_minus = ticks_slot_minus;
user_op->params.update.lazy = lazy;
user_op->params.update.force = force;
#if defined(CONFIG_BT_TICKER_EXT)
user_op->params.update.must_expire = must_expire;
#endif /* CONFIG_BT_TICKER_EXT */
user_op->status = TICKER_STATUS_BUSY;
user_op->fp_op_func = fp_op_func;
user_op->op_context = op_context;

View file

@ -30,6 +30,7 @@
#define TICKER_NULL_SLOT 0
#define TICKER_NULL_LAZY 0
#define TICKER_NULL_MUST_EXPIRE 0
/**
* @}
*/
@ -66,9 +67,14 @@
#define TICKER_CALL_ID_PROGRAM 5
/* Use to ensure callback is invoked in all intervals, even when latencies
* occur
* occur.
*/
#define TICKER_LAZY_MUST_EXPIRE 0xFFFF
#define TICKER_LAZY_MUST_EXPIRE 0xFFFF
/* Use in ticker_start to set lazy to 0 and do not change the must_expire
* state.
*/
#define TICKER_LAZY_MUST_EXPIRE_KEEP 0xFFFE
/* Set this priority to ensure ticker node is always scheduled. Only one
* ticker node can have priority TICKER_PRIORITY_CRITICAL at a time
@ -158,5 +164,12 @@ uint32_t ticker_start_ext(uint8_t instance_index, uint8_t user_id, uint8_t ticke
ticker_timeout_func fp_timeout_func, void *context,
ticker_op_func fp_op_func, void *op_context,
struct ticker_ext *ext_data);
uint32_t ticker_update_ext(uint8_t instance_index, uint8_t user_id,
uint8_t ticker_id, uint32_t ticks_drift_plus,
uint32_t ticks_drift_minus,
uint32_t ticks_slot_plus, uint32_t ticks_slot_minus,
uint16_t lazy, uint8_t force,
ticker_op_func fp_op_func, void *op_context,
uint8_t must_expire);
#endif /* CONFIG_BT_TICKER_EXT */
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */