26
26
#define FLASH_SYNC_SWITCHING_TIME (FLASH_RADIO_ABORT_DELAY_US +\
27
27
FLASH_RADIO_WORK_DELAY_US)
28
28
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 */
33
34
int result ;
34
- };
35
-
36
- static struct ticker_sync_context _ticker_sync_context ;
35
+ } _ticker_sync_context ;
37
36
38
37
/* semaphore for synchronization of flash operations */
39
38
static struct k_sem sem_sync ;
@@ -151,6 +150,7 @@ static void time_slot_callback_abort(uint32_t ticks_at_expire,
151
150
void * context )
152
151
{
153
152
ll_radio_state_abort ();
153
+
154
154
time_slot_delay (ticks_at_expire ,
155
155
HAL_TICKER_US_TO_TICKS (FLASH_RADIO_WORK_DELAY_US ),
156
156
time_slot_callback_work ,
@@ -163,6 +163,18 @@ static void time_slot_callback_prepare(uint32_t ticks_at_expire,
163
163
uint16_t lazy , uint8_t force ,
164
164
void * context )
165
165
{
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
+
166
178
#if defined(CONFIG_BT_CTLR_LOW_LAT )
167
179
time_slot_callback_abort (ticks_at_expire , ticks_drift , remainder , lazy ,
168
180
force , context );
@@ -178,6 +190,7 @@ static void time_slot_callback_prepare(uint32_t ticks_at_expire,
178
190
int nrf_flash_sync_init (void )
179
191
{
180
192
k_sem_init (& sem_sync , 0 , 1 );
193
+
181
194
return 0 ;
182
195
}
183
196
@@ -193,10 +206,26 @@ void nrf_flash_sync_set_context(uint32_t duration)
193
206
int nrf_flash_sync_exe (struct flash_op_desc * op_desc )
194
207
{
195
208
uint8_t instance_index ;
209
+ uint32_t ticks_elapsed ;
210
+ uint32_t ticks_slot ;
211
+ uint32_t ticks_now ;
196
212
uint8_t ticker_id ;
197
213
uint32_t ret ;
198
214
int result ;
199
215
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
+ _ticker_sync_context .ticks_previous = ticks_now ;
223
+ ticks_slot = HAL_TICKER_US_TO_TICKS (_ticker_sync_context .slot );
224
+ if (ticks_elapsed < ticks_slot ) {
225
+ /* Set ticker start reference one flash slot interval in the past */
226
+ ticks_now = ticker_ticks_diff_get (ticks_now , ticks_slot );
227
+ }
228
+
200
229
/* Get the ticker instance and ticker id for flash operations */
201
230
ll_timeslice_ticker_id_get (& instance_index , & ticker_id );
202
231
@@ -205,7 +234,7 @@ int nrf_flash_sync_exe(struct flash_op_desc *op_desc)
205
234
3 , /* user id for thread mode */
206
235
/* (MAYFLY_CALL_ID_PROGRAM) */
207
236
ticker_id , /* flash ticker id */
208
- ticker_ticks_now_get () , /* current tick */
237
+ ticks_now , /* current tick */
209
238
0 , /* first int. immediately */
210
239
/* period */
211
240
HAL_TICKER_US_TO_TICKS (
0 commit comments