Skip to content

Commit 22575e5

Browse files
committed
Bluetooth: Controller: Fix flash sync start from starving connection
Fix flash sync start from repeatedly forcing connection event be skipped. Space new flash operation to be placed in the past so that it does not force itself on to an overlapping connection event. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
1 parent 732a3a5 commit 22575e5

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

subsys/bluetooth/controller/flash/soc_flash_nrf_ticker.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@
2626
#define FLASH_SYNC_SWITCHING_TIME (FLASH_RADIO_ABORT_DELAY_US +\
2727
FLASH_RADIO_WORK_DELAY_US)
2828

29-
struct ticker_sync_context {
30-
uint32_t interval; /* timeslot interval. */
31-
uint32_t slot; /* timeslot length. */
32-
uint32_t ticks_begin; /* timeslot begin timestamp */
29+
static struct {
30+
uint32_t interval; /* timeslot interval. */
31+
uint32_t slot; /* timeslot length. */
32+
uint32_t ticks_begin; /* timeslot begin timestamp */
33+
uint32_t ticks_previous; /* timeslot previous reference */
3334
int result;
34-
};
35-
36-
static struct ticker_sync_context _ticker_sync_context;
35+
} _ticker_sync_context;
3736

3837
/* semaphore for synchronization of flash operations */
3938
static struct k_sem sem_sync;
@@ -151,6 +150,7 @@ static void time_slot_callback_abort(uint32_t ticks_at_expire,
151150
void *context)
152151
{
153152
ll_radio_state_abort();
153+
154154
time_slot_delay(ticks_at_expire,
155155
HAL_TICKER_US_TO_TICKS(FLASH_RADIO_WORK_DELAY_US),
156156
time_slot_callback_work,
@@ -163,6 +163,18 @@ static void time_slot_callback_prepare(uint32_t ticks_at_expire,
163163
uint16_t lazy, uint8_t force,
164164
void *context)
165165
{
166+
uint32_t ticks_elapsed;
167+
uint32_t ticks_now;
168+
169+
/* Skip flash operation if in the past, this can be when requested in the past due to
170+
* flash operations requested too often.
171+
*/
172+
ticks_now = ticker_ticks_now_get();
173+
ticks_elapsed = ticker_ticks_diff_get(ticks_now, ticks_at_expire);
174+
if (ticks_elapsed > HAL_TICKER_US_TO_TICKS(FLASH_RADIO_WORK_DELAY_US)) {
175+
return;
176+
}
177+
166178
#if defined(CONFIG_BT_CTLR_LOW_LAT)
167179
time_slot_callback_abort(ticks_at_expire, ticks_drift, remainder, lazy,
168180
force, context);
@@ -178,6 +190,7 @@ static void time_slot_callback_prepare(uint32_t ticks_at_expire,
178190
int nrf_flash_sync_init(void)
179191
{
180192
k_sem_init(&sem_sync, 0, 1);
193+
181194
return 0;
182195
}
183196

@@ -193,10 +206,28 @@ void nrf_flash_sync_set_context(uint32_t duration)
193206
int nrf_flash_sync_exe(struct flash_op_desc *op_desc)
194207
{
195208
uint8_t instance_index;
209+
uint32_t ticks_elapsed;
210+
uint32_t ticks_slot;
211+
uint32_t ticks_now;
196212
uint8_t ticker_id;
197213
uint32_t ret;
198214
int result;
199215

216+
/* Check if flash operation request too often that can starve connection events.
217+
* We will request to start ticker in the past so that it does not `force` itself onto
218+
* scheduling by causing connection events to be skipped.
219+
*/
220+
ticks_now = ticker_ticks_now_get();
221+
ticks_elapsed = ticker_ticks_diff_get(ticks_now, _ticker_sync_context.ticks_previous);
222+
ticks_slot = HAL_TICKER_US_TO_TICKS(_ticker_sync_context.slot);
223+
if (ticks_elapsed < ticks_slot) {
224+
uint32_t ticks_interval = HAL_TICKER_US_TO_TICKS(_ticker_sync_context.interval);
225+
226+
/* Set ticker start reference one flash slot interval in the past */
227+
ticks_now -= ticks_interval;
228+
}
229+
_ticker_sync_context.ticks_previous = ticks_now;
230+
200231
/* Get the ticker instance and ticker id for flash operations */
201232
ll_timeslice_ticker_id_get(&instance_index, &ticker_id);
202233

@@ -205,7 +236,7 @@ int nrf_flash_sync_exe(struct flash_op_desc *op_desc)
205236
3, /* user id for thread mode */
206237
/* (MAYFLY_CALL_ID_PROGRAM) */
207238
ticker_id, /* flash ticker id */
208-
ticker_ticks_now_get(), /* current tick */
239+
ticks_now, /* current tick */
209240
0, /* first int. immediately */
210241
/* period */
211242
HAL_TICKER_US_TO_TICKS(

0 commit comments

Comments
 (0)