You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/02/22 19:53:00 UTC
[mynewt-nimble] 01/05: nimble/ll: Remove strict conn scheduling
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit b3990580fb8a7eba88223489f8a9b54a141f1c0c
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Thu Feb 3 17:05:20 2022 +0100
nimble/ll: Remove strict conn scheduling
This removes strict scheduling code as we'll add new, more configurable
implementation instead.
---
nimble/controller/include/controller/ble_ll_conn.h | 4 -
.../controller/include/controller/ble_ll_sched.h | 33 ---
nimble/controller/src/ble_ll_conn.c | 27 +-
nimble/controller/src/ble_ll_sched.c | 296 ---------------------
nimble/controller/syscfg.yml | 33 +--
5 files changed, 13 insertions(+), 380 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h
index cd219cb..015bac75 100644
--- a/nimble/controller/include/controller/ble_ll_conn.h
+++ b/nimble/controller/include/controller/ble_ll_conn.h
@@ -230,10 +230,6 @@ struct ble_ll_conn_sm
uint8_t last_unmapped_chan;
uint8_t num_used_chans;
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- uint8_t period_occ_mask; /* mask: period 0 = 0x01, period 3 = 0x08 */
-#endif
-
/* Ack/Flow Control */
uint8_t tx_seqnum; /* note: can be 1 bit */
uint8_t next_exp_seqnum; /* note: can be 1 bit */
diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h
index 56399d2..b3f7d19 100644
--- a/nimble/controller/include/controller/ble_ll_sched.h
+++ b/nimble/controller/include/controller/ble_ll_sched.h
@@ -79,39 +79,6 @@ extern uint8_t g_ble_ll_sched_offset_ticks;
struct ble_ll_sched_item;
typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch);
typedef void (*sched_remove_cb_func)(struct ble_ll_sched_item *sch);
-/*
- * Strict connection scheduling (for the master) is different than how
- * connections are normally scheduled. With strict connection scheduling we
- * introduce the concept of a "period". A period is a collection of slots. Each
- * slot is 1.25 msecs in length. The number of slots in a period is determined
- * by the syscfg value BLE_LL_CONN_INIT_SLOTS. A collection of periods is called
- * an epoch. The length of an epoch is determined by the number of connections
- * (BLE_MAX_CONNECTIONS plus BLE_LL_ADD_STRICT_SCHED_PERIODS). Connections
- * will be scheduled at period boundaries. Any scanning/initiating/advertising
- * will be done in unused periods, if possible.
- */
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
-#define BLE_LL_SCHED_PERIODS (MYNEWT_VAL(BLE_MAX_CONNECTIONS) + \
- MYNEWT_VAL(BLE_LL_ADD_STRICT_SCHED_PERIODS))
-
-struct ble_ll_sched_obj
-{
- uint8_t sch_num_occ_periods;
- uint32_t sch_occ_period_mask;
- uint32_t sch_ticks_per_period;
- uint32_t sch_ticks_per_epoch;
- uint32_t sch_epoch_start;
-};
-
-extern struct ble_ll_sched_obj g_ble_ll_sched_data;
-
-/*
- * XXX: TODO:
- * -> How do we know epoch start is up to date? Not wrapped?
- * -> for now, only do this with no more than 32 connections.
- * -> Do not let initiating occur if no empty sched slots
- */
-#endif
/*
* Schedule item
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index 33a666a..f3e40a2 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -761,10 +761,6 @@ ble_ll_conn_continue_rx_encrypt(void *arg)
static uint32_t
ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm)
{
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- uint32_t ce_end;
- ce_end = connsm->ce_end_time;
-#else
uint32_t ce_end;
uint32_t next_sched_time;
uint8_t rem_us;
@@ -781,7 +777,6 @@ ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm)
ce_end = next_sched_time;
}
}
-#endif
return ce_end;
}
@@ -1934,16 +1929,6 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
/* Make sure events off queue */
ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end);
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- /* Remove from occupied periods */
- OS_ENTER_CRITICAL(sr);
- BLE_LL_ASSERT(g_ble_ll_sched_data.sch_num_occ_periods > 0);
- BLE_LL_ASSERT(g_ble_ll_sched_data.sch_occ_period_mask & connsm->period_occ_mask);
- --g_ble_ll_sched_data.sch_num_occ_periods;
- g_ble_ll_sched_data.sch_occ_period_mask &= ~connsm->period_occ_mask;
- OS_EXIT_CRITICAL(sr);
-#endif
-
/* Connection state machine is now idle */
connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
@@ -2219,12 +2204,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
* Calculate ce end time. For a peripgheral, we need to add window widening
* and the transmit window if we still have one.
*/
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- itvl = g_ble_ll_sched_data.sch_ticks_per_period;
-#else
itvl = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
BLE_LL_SCHED_USECS_PER_SLOT);
-#endif
+
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) {
@@ -2333,17 +2315,10 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr)
connsm->periph_cur_tx_win_usecs =
connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS;
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- connsm->ce_end_time = connsm->anchor_point +
- g_ble_ll_sched_data.sch_ticks_per_period +
- ble_ll_tmr_u2t(connsm->periph_cur_tx_win_usecs) + 1;
-
-#else
connsm->ce_end_time = connsm->anchor_point +
ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
BLE_LL_SCHED_USECS_PER_SLOT +
connsm->periph_cur_tx_win_usecs) + 1;
-#endif
/* Start the scheduler for the first connection event */
while (ble_ll_sched_conn_periph_new(connsm)) {
diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c
index b7d8cf6..14c8753 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -64,10 +64,6 @@ typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch,
static TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q;
static uint8_t g_ble_ll_sched_q_head_changed;
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
-struct ble_ll_sched_obj g_ble_ll_sched_data;
-#endif
-
static int
preempt_any(struct ble_ll_sched_item *sch,
struct ble_ll_sched_item *item)
@@ -284,39 +280,6 @@ done:
return sch->enqueued ? 0 : -1;
}
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
-/**
- * Checks if two events in the schedule will overlap in time. NOTE: consecutive
- * schedule items can end and start at the same time.
- *
- * @param s1
- * @param s2
- *
- * @return int 0: dont overlap 1:overlap
- */
-static int
-ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1,
- struct ble_ll_sched_item *s2)
-{
- int rc;
-
- rc = 1;
- if (LL_TMR_LT(s1->start_time, s2->start_time)) {
- /* Make sure this event does not overlap current event */
- if (LL_TMR_LEQ(s1->end_time, s2->start_time)) {
- rc = 0;
- }
- } else {
- /* Check for overlap */
- if (LL_TMR_GEQ(s1->start_time, s2->end_time)) {
- rc = 0;
- }
- }
-
- return rc;
-}
-#endif
-
/*
* Determines if the schedule item overlaps the currently running schedule
* item. We only care about connection schedule items
@@ -338,21 +301,6 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch)
return rc;
}
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
-static struct ble_ll_sched_item *
-ble_ll_sched_insert_if_empty(struct ble_ll_sched_item *sch)
-{
- struct ble_ll_sched_item *entry;
-
- entry = TAILQ_FIRST(&g_ble_ll_sched_q);
- if (!entry) {
- TAILQ_INSERT_HEAD(&g_ble_ll_sched_q, sch, link);
- sch->enqueued = 1;
- }
- return entry;
-}
-#endif
-
int
ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
{
@@ -420,241 +368,6 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
*
* @return int
*/
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
-int
-ble_ll_sched_central_new(struct ble_ll_conn_sm *connsm,
- struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len)
-{
- int rc;
- os_sr_t sr;
- uint32_t initial_start;
- uint32_t earliest_start;
- uint32_t earliest_end;
- uint32_t dur;
- uint32_t itvl_t;
- uint32_t adv_rxend;
- int i;
- uint32_t tpp;
- uint32_t tse;
- uint32_t np;
- uint32_t cp;
- uint32_t tick_in_period;
-
- struct ble_ll_sched_item *entry;
- struct ble_ll_sched_item *sch;
-
- /* Better have a connsm */
- BLE_LL_ASSERT(connsm != NULL);
-
- /* Get schedule element from connection */
- rc = -1;
- sch = &connsm->conn_sch;
-
- /* XXX:
- * The calculations for the 32kHz crystal bear alot of explanation. The
- * earliest possible time that the central can start the connection with a
- * peripheral is 1.25 msecs from the end of the connection request. The
- * connection request is sent an IFS time from the end of the advertising
- * packet that was received plus the time it takes to send the connection
- * request. At 1 Mbps, this is 1752 usecs, or 57.41 ticks. Using 57 ticks
- * makes us off ~13 usecs. Since we dont want to actually calculate the
- * receive end time tick (this would take too long), we assume the end of
- * the advertising PDU is 'now' (we call os_cputime_get32). We dont know
- * how much time it will take to service the ISR but if we are more than the
- * rx to tx time of the chip we will not be successful transmitting the
- * connect request. All this means is that we presume that the peripheral will
- * receive the connect request later than we expect but no earlier than
- * 13 usecs before (this is important).
- *
- * The code then attempts to schedule the connection at the
- * earliest time although this may not be possible. When the actual
- * schedule start time is determined, the central has to determine if this
- * time is more than a transmit window offset interval (1.25 msecs). The
- * central has to tell the peripheral how many transmit window offsets there are
- * from the earliest possible time to when the actual transmit start will
- * occur. Later in this function you will see the calculation. The actual
- * transmission start has to occur within the transmit window. The transmit
- * window interval is in units of 1.25 msecs and has to be at least 1. To
- * make things a bit easier (but less power efficient for the peripheral), we
- * use a transmit window of 2. We do this because we dont quite know the
- * exact start of the transmission and if we are too early or too late we
- * could miss the transmit window. A final note: the actual transmission
- * start (the anchor point) is sched offset ticks from the schedule start
- * time. We dont add this to the calculation when calculating the window
- * offset. The reason we dont do this is we want to insure we transmit
- * after the window offset we tell the peripheral. For example, say we think
- * we are transmitting 1253 usecs from the earliest start. This would cause
- * us to send a transmit window offset of 1. Since we are actually
- * transmitting earlier than the peripheral thinks we could end up transmitting
- * before the window offset. Transmitting later is fine since we have the
- * transmit window to do so. Transmitting before is bad, since the peripheral
- * wont be listening. We could do better calculation if we wanted to use
- * a transmit window of 1 as opposed to 2, but for now we dont care.
- */
- dur = ble_ll_tmr_u2t(g_ble_ll_sched_data.sch_ticks_per_period);
- adv_rxend = ble_ll_tmr_get();
- if (ble_hdr->rxinfo.channel >= BLE_PHY_NUM_DATA_CHANS) {
- /*
- * We received packet on advertising channel which means this is a legacy
- * PDU on 1 Mbps - we do as described above.
- */
- earliest_start = adv_rxend + 57;
- } else {
- /*
- * The calculations are similar as above.
- *
- * We received packet on data channel which means this is AUX_ADV_IND
- * received on secondary adv channel. We can schedule first packet at
- * the earliest after "T_IFS + AUX_CONNECT_REQ + transmitWindowDelay".
- * AUX_CONNECT_REQ and transmitWindowDelay times vary depending on which
- * PHY we received on.
- *
- */
- if (ble_hdr->rxinfo.phy == BLE_PHY_1M) {
- // 150 + 352 + 2500 = 3002us = 98.37 ticks
- earliest_start = adv_rxend + 98;
- } else if (ble_hdr->rxinfo.phy == BLE_PHY_2M) {
- // 150 + 180 + 2500 = 2830us = 92.73 ticks
- earliest_start = adv_rxend + 93;
- } else if (ble_hdr->rxinfo.phy == BLE_PHY_CODED) {
- // 150 + 2896 + 3750 = 6796us = 222.69 ticks
- earliest_start = adv_rxend + 223;
- } else {
- BLE_LL_ASSERT(0);
- }
- }
- earliest_start += MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) *
- BLE_LL_SCHED_USECS_PER_SLOT;
- itvl_t = connsm->conn_itvl_ticks;
-
- /* We have to find a place for this schedule */
- OS_ENTER_CRITICAL(sr);
-
- /*
- * Are there any allocated periods? If not, set epoch start to earliest
- * time
- */
- if (g_ble_ll_sched_data.sch_num_occ_periods == 0) {
- g_ble_ll_sched_data.sch_epoch_start = earliest_start;
- cp = 0;
- } else {
- /*
- * Earliest start must occur on period boundary.
- * (tse = ticks since epoch)
- */
- tpp = g_ble_ll_sched_data.sch_ticks_per_period;
- tse = earliest_start - g_ble_ll_sched_data.sch_epoch_start;
- np = tse / tpp;
- cp = np % BLE_LL_SCHED_PERIODS;
- tick_in_period = tse - (np * tpp);
- if (tick_in_period != 0) {
- ++cp;
- if (cp == BLE_LL_SCHED_PERIODS) {
- cp = 0;
- }
- earliest_start += (tpp - tick_in_period);
- }
-
- /* Now find first un-occupied period starting from cp */
- for (i = 0; i < BLE_LL_SCHED_PERIODS; ++i) {
- if (g_ble_ll_sched_data.sch_occ_period_mask & (1 << cp)) {
- ++cp;
- if (cp == BLE_LL_SCHED_PERIODS) {
- cp = 0;
- }
- earliest_start += tpp;
- } else {
- /* not occupied */
- break;
- }
- }
- /* Should never happen but if it does... */
- if (i == BLE_LL_SCHED_PERIODS) {
- OS_EXIT_CRITICAL(sr);
- return rc;
- }
- }
-
- sch->start_time = earliest_start;
- initial_start = earliest_start;
- earliest_end = earliest_start + dur;
-
- if (!ble_ll_sched_insert_if_empty(sch)) {
- /* Nothing in schedule. Schedule as soon as possible */
- rc = 0;
- connsm->tx_win_off = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET);
- } else {
- ble_ll_tmr_stop(&g_ble_ll_sched_timer);
- TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
- /* Set these because overlap function needs them to be set */
- sch->start_time = earliest_start;
- sch->end_time = earliest_end;
-
- /* We can insert if before entry in list */
- if (LL_TMR_LEQ(sch->end_time, entry->start_time)) {
- if ((earliest_start - initial_start) <= itvl_t) {
- rc = 0;
- TAILQ_INSERT_BEFORE(entry, sch, link);
- }
- break;
- }
-
- /* Check for overlapping events */
- if (ble_ll_sched_is_overlap(sch, entry)) {
- /* Earliest start is end of this event since we overlap */
- earliest_start = entry->end_time;
- earliest_end = earliest_start + dur;
- }
- }
-
- /* Must be able to schedule within one connection interval */
- if (!entry) {
- if ((earliest_start - initial_start) <= itvl_t) {
- rc = 0;
- TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link);
- }
- }
-
- if (!rc) {
- /* calculate number of window offsets. Each offset is 1.25 ms */
- sch->enqueued = 1;
- /*
- * NOTE: we dont add sched offset ticks as we want to under-estimate
- * the transmit window slightly since the window size is currently
- * 2 when using a 32768 crystal.
- */
- dur = ble_ll_tmr_t2u(earliest_start - initial_start);
- connsm->tx_win_off = dur / BLE_LL_CONN_TX_OFF_USECS;
- }
- }
-
- if (!rc) {
- sch->start_time = earliest_start;
- sch->end_time = earliest_end;
- /*
- * Since we have the transmit window to transmit in, we dont need
- * to set the anchor point usecs; just transmit to the nearest tick.
- */
- connsm->anchor_point = earliest_start + g_ble_ll_sched_offset_ticks;
- connsm->anchor_point_usecs = 0;
- connsm->ce_end_time = earliest_end;
- connsm->period_occ_mask = (1 << cp);
- g_ble_ll_sched_data.sch_occ_period_mask |= connsm->period_occ_mask;
- ++g_ble_ll_sched_data.sch_num_occ_periods;
- }
-
-
- /* Get head of list to restart timer */
- sch = TAILQ_FIRST(&g_ble_ll_sched_q);
- ble_ll_rfmgmt_sched_changed(sch);
-
- OS_EXIT_CRITICAL(sr);
-
- ble_ll_tmr_start(&g_ble_ll_sched_timer, sch->start_time);
-
- return rc;
-}
-#else
int
ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm,
struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len)
@@ -778,7 +491,6 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm,
return rc;
}
-#endif
/**
* Schedules a peripheral connection for the first time.
@@ -1388,14 +1100,6 @@ ble_ll_sched_init(void)
/* Initialize cputimer for the scheduler */
ble_ll_tmr_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL);
-#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
- memset(&g_ble_ll_sched_data, 0, sizeof(struct ble_ll_sched_obj));
- g_ble_ll_sched_data.sch_ticks_per_period =
- ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_USECS_PER_PERIOD));
- g_ble_ll_sched_data.sch_ticks_per_epoch = BLE_LL_SCHED_PERIODS *
- g_ble_ll_sched_data.sch_ticks_per_period;
-#endif
-
g_ble_ll_sched_q_head_changed = 0;
return 0;
diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml
index b565ce4..8ecdd2c 100644
--- a/nimble/controller/syscfg.yml
+++ b/nimble/controller/syscfg.yml
@@ -146,27 +146,6 @@ syscfg.defs:
ensure interoperability with such devices set this value to 2 (or more).
value: '0'
- # Strict scheduling
- BLE_LL_STRICT_CONN_SCHEDULING:
- description: >
- Forces the scheduler on a central to schedule connections in fixed
- time intervals called periods. If set to 0, the scheduler is not forced
- to do this. If set to 1, the scheduler will only schedule connections at
- period boundaries. See comments in ble_ll_sched.h for more details.
- value: '0'
-
- BLE_LL_ADD_STRICT_SCHED_PERIODS:
- description: >
- The number of additional periods that will be allocated for strict
- scheduling. The total # of periods allocated for strict scheduling
- will be equal to the number of connections plus this number.
- value: '0'
-
- BLE_LL_USECS_PER_PERIOD:
- description: >
- The number of usecs per period.
- value: '3250'
-
# The number of random bytes to store
BLE_LL_RNG_BUFSIZE:
description: >
@@ -505,6 +484,18 @@ syscfg.defs:
description: Superseded by BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG
value: 0
defaunt: 1
+ BLE_LL_STRICT_CONN_SCHEDULING:
+ description: Superseded by BLE_LL_CONN_STRICT_SCHED
+ value: 0
+ defunct: 1
+ BLE_LL_ADD_STRICT_SCHED_PERIODS:
+ description: Superseded by BLE_LL_CONN_STRICT_SCHED
+ value: 0
+ defunct: 1
+ BLE_LL_USECS_PER_PERIOD:
+ description: Superseded by BLE_LL_CONN_STRICT_SCHED
+ value: 0
+ defunct: 1
syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV:
BLE_LL_CFG_FEAT_LE_CSA2: 1