Skip to content

Commit 3c23c6f

Browse files
cvinayakjhedberg
authored andcommitted
Bluetooth: controller: Fix assert due to stale tick count
Fixed assert due to stale tick count in role event preparation. This happens when ticker timeout expiry is delayed from the requested realtime anchor, due to thread mode processing overheads and occurring interrupts therein, if any, that added a delay between requested anchor tick and actual scheduling for the requested ticker timeout. The assert is reproduced in bt shell by starting advertising and following it with continuous scanning (interval 2.5ms, window 2.5ms), on nRF51x. If the overheads and/or a advertiser event delayed the scheduling of scanner by over 2.5ms, then the preparation of scanner asserted. The assert has been fixed by checking for stale tick count at expiry in role event preparation and skip the event gracefully. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 3707096 commit 3c23c6f

File tree

1 file changed

+55
-31
lines changed
  • subsys/bluetooth/controller/ll_sw

1 file changed

+55
-31
lines changed

subsys/bluetooth/controller/ll_sw/ctrl.c

+55-31
Original file line numberDiff line numberDiff line change
@@ -4323,20 +4323,26 @@ static void event_stop(u32_t ticks_at_expire, u32_t remainder,
43234323
LL_ASSERT(!retval);
43244324
}
43254325

4326-
static void event_common_prepare(u32_t ticks_at_expire,
4327-
u32_t remainder,
4328-
u32_t *ticks_xtal_to_start,
4329-
u32_t *ticks_active_to_start,
4330-
u32_t ticks_preempt_to_start,
4331-
u8_t ticker_id,
4332-
ticker_timeout_func ticker_timeout_fp,
4333-
void *context)
4326+
static u32_t event_common_prepare(u32_t ticks_at_expire,
4327+
u32_t remainder,
4328+
u32_t *ticks_xtal_to_start,
4329+
u32_t *ticks_active_to_start,
4330+
u32_t ticks_preempt_to_start,
4331+
u8_t ticker_id,
4332+
ticker_timeout_func ticker_timeout_fp,
4333+
void *context)
43344334
{
43354335
u32_t ticker_status;
43364336
u32_t _ticks_xtal_to_start = *ticks_xtal_to_start;
43374337
u32_t _ticks_active_to_start = *ticks_active_to_start;
43384338
u32_t ticks_to_start;
43394339

4340+
/* Check for stale ticks_at_expire */
4341+
if (ticker_ticks_diff_get(ticker_ticks_now_get(), ticks_at_expire) >
4342+
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US)) {
4343+
return 1;
4344+
}
4345+
43404346
/* in case this event is short prepare, xtal to start duration will be
43414347
* active to start duration.
43424348
*/
@@ -4479,6 +4485,8 @@ static void event_common_prepare(u32_t ticks_at_expire,
44794485
LL_ASSERT(!retval);
44804486
}
44814487
#endif /* CONFIG_BLUETOOTH_CONTROLLER_XTAL_ADVANCED */
4488+
4489+
return 0;
44824490
}
44834491

44844492
static u8_t chan_sel_remap(u8_t *chan_map, u8_t chan_index)
@@ -4757,19 +4765,23 @@ static void adv_scan_configure(u8_t phy, u8_t flags)
47574765
void radio_event_adv_prepare(u32_t ticks_at_expire, u32_t remainder,
47584766
u16_t lazy, void *context)
47594767
{
4768+
u32_t err;
4769+
47604770
ARG_UNUSED(lazy);
47614771
ARG_UNUSED(context);
47624772

47634773
DEBUG_RADIO_PREPARE_A(1);
47644774

47654775
LL_ASSERT(!_radio.ticker_id_prepare);
4766-
_radio.ticker_id_prepare = RADIO_TICKER_ID_ADV;
47674776

4768-
event_common_prepare(ticks_at_expire, remainder,
4769-
&_radio.advertiser.hdr.ticks_xtal_to_start,
4770-
&_radio.advertiser.hdr.ticks_active_to_start,
4771-
_radio.advertiser.hdr.ticks_preempt_to_start,
4772-
RADIO_TICKER_ID_ADV, event_adv, NULL);
4777+
err = event_common_prepare(ticks_at_expire, remainder,
4778+
&_radio.advertiser.hdr.ticks_xtal_to_start,
4779+
&_radio.advertiser.hdr.ticks_active_to_start,
4780+
_radio.advertiser.hdr.ticks_preempt_to_start,
4781+
RADIO_TICKER_ID_ADV, event_adv, NULL);
4782+
if (!err) {
4783+
_radio.ticker_id_prepare = RADIO_TICKER_ID_ADV;
4784+
}
47734785

47744786
DEBUG_RADIO_PREPARE_A(0);
47754787
}
@@ -4972,19 +4984,25 @@ void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
49724984
static void event_scan_prepare(u32_t ticks_at_expire, u32_t remainder,
49734985
u16_t lazy, void *context)
49744986
{
4987+
u32_t err;
4988+
49754989
ARG_UNUSED(lazy);
49764990
ARG_UNUSED(context);
49774991

49784992
DEBUG_RADIO_PREPARE_O(1);
49794993

49804994
LL_ASSERT(!_radio.ticker_id_prepare);
4981-
_radio.ticker_id_prepare = RADIO_TICKER_ID_SCAN;
49824995

4983-
event_common_prepare(ticks_at_expire, remainder,
4984-
&_radio.scanner.hdr.ticks_xtal_to_start,
4985-
&_radio.scanner.hdr.ticks_active_to_start,
4986-
_radio.scanner.hdr.ticks_preempt_to_start,
4987-
RADIO_TICKER_ID_SCAN, event_scan, NULL);
4996+
err = event_common_prepare(ticks_at_expire, remainder,
4997+
&_radio.scanner.hdr.ticks_xtal_to_start,
4998+
&_radio.scanner.hdr.ticks_active_to_start,
4999+
_radio.scanner.hdr.ticks_preempt_to_start,
5000+
RADIO_TICKER_ID_SCAN, event_scan, NULL);
5001+
if (err) {
5002+
goto skip;
5003+
}
5004+
5005+
_radio.ticker_id_prepare = RADIO_TICKER_ID_SCAN;
49885006

49895007
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCHED_ADVANCED)
49905008
/* calc next group in us for the anchor where first connection event
@@ -5021,6 +5039,7 @@ static void event_scan_prepare(u32_t ticks_at_expire, u32_t remainder,
50215039
}
50225040
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCHED_ADVANCED */
50235041

5042+
skip:
50245043
DEBUG_RADIO_PREPARE_O(0);
50255044
}
50265045

@@ -6360,10 +6379,9 @@ static void event_connection_prepare(u32_t ticks_at_expire,
63606379
struct connection *conn)
63616380
{
63626381
u16_t event_counter;
6382+
u32_t err;
63636383

63646384
LL_ASSERT(!_radio.ticker_id_prepare);
6365-
_radio.ticker_id_prepare =
6366-
RADIO_TICKER_ID_FIRST_CONNECTION + conn->handle;
63676385

63686386
/* Calc window widening */
63696387
if (conn->role.slave.role != 0) {
@@ -6497,17 +6515,23 @@ static void event_connection_prepare(u32_t ticks_at_expire,
64976515
}
64986516
#endif /* CONFIG_BLUETOOTH_CONTROLLER_DATA_LENGTH */
64996517

6500-
/* Setup XTAL startup and radio active events */
6501-
event_common_prepare(ticks_at_expire, remainder,
6502-
&conn->hdr.ticks_xtal_to_start,
6503-
&conn->hdr.ticks_active_to_start,
6504-
conn->hdr.ticks_preempt_to_start,
6505-
(RADIO_TICKER_ID_FIRST_CONNECTION + conn->handle),
6506-
(conn->role.slave.role != 0) ? event_slave : event_master,
6507-
conn);
6508-
65096518
/* store the next event counter value */
65106519
conn->event_counter = event_counter + 1;
6520+
6521+
/* Setup XTAL startup and radio active events */
6522+
err = event_common_prepare(ticks_at_expire, remainder,
6523+
&conn->hdr.ticks_xtal_to_start,
6524+
&conn->hdr.ticks_active_to_start,
6525+
conn->hdr.ticks_preempt_to_start,
6526+
(RADIO_TICKER_ID_FIRST_CONNECTION +
6527+
conn->handle),
6528+
(conn->role.slave.role != 0) ? event_slave :
6529+
event_master,
6530+
conn);
6531+
if (!err) {
6532+
_radio.ticker_id_prepare = RADIO_TICKER_ID_FIRST_CONNECTION +
6533+
conn->handle;
6534+
}
65116535
}
65126536

65136537
static void connection_configure(struct connection *conn)

0 commit comments

Comments
 (0)