Skip to content

Commit f1838f8

Browse files
committed
samples: bluetooth: iso_time_sync: Fix iso_tx.c when asserts enabled
This sample would assert if asserts were enabled, this is due to calling bt_iso_chan_send/bt_iso_chan_send_ts which in turn call sched_lock, which is not allowed to be called from a timer_isr. To fix this, schedule a work queue to run at the desired time. Another assert would then occur as we were sending SDUs with incorrect timestamps due to a race condition between the iso_sent callback and iso_connected callback meaning we would add an incorrect timestamp to some sdus. This causes the controller to return an error and the buffer gets lost, leading to an assert. Signed-off-by: Sean Madigan <[email protected]>
1 parent 42f5f57 commit f1838f8

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ Amazon Sidewalk samples
240240

241241
Bluetooth samples
242242
-----------------
243+
* :ref:`bluetooth_isochronous_time_synchronization` sample:
244+
245+
* Fixed an issue where the sample would assert with the :kconfig:option:`CONFIG_ASSERT` Kconfig option enabled.
246+
This was due to calling the :c:func:`bt_iso_chan_send` function from a timer ISR handler and sending SDUs to the controller with invalid timestamps.
243247

244248
|no_changes_yet_note|
245249

samples/bluetooth/iso_time_sync/prj.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
CONFIG_NCS_SAMPLES_DEFAULTS=y
2+
13
CONFIG_BT=y
24
CONFIG_BT_ISO_BROADCASTER=y
35
CONFIG_BT_ISO_SYNC_RECEIVER=y

samples/bluetooth/iso_time_sync/src/iso_tx.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ static bool first_sdu_sent;
4646
static uint32_t tx_sdu_timestamp_us;
4747
static uint32_t num_sdus_sent;
4848

49-
static void sdu_timer_expired(struct k_timer *timer);
50-
static K_TIMER_DEFINE(sdu_timer, sdu_timer_expired, NULL);
49+
static void sdu_work_handler(struct k_work *work);
50+
static K_WORK_DELAYABLE_DEFINE(sdu_work, sdu_work_handler);
5151

5252
static struct bt_iso_chan_ops iso_ops = {
5353
.connected = iso_connected,
@@ -217,6 +217,7 @@ static void send_next_sdu_on_all_channels(void)
217217
* To avoid reading the timestamp both after sending SDUs and after
218218
* the first SDU, we break out early here the very first event.
219219
*/
220+
first_sdu_sent = true;
220221
break;
221222
}
222223
}
@@ -289,8 +290,6 @@ static bool send_more_sdus_with_same_timestamp(struct bt_iso_chan *chan)
289290
}
290291
}
291292

292-
/* The very first SDU is sent on one channel only. */
293-
first_sdu_sent = true;
294293
return false;
295294
}
296295

@@ -354,7 +353,7 @@ static void iso_sent(struct bt_iso_chan *chan)
354353

355354
iso_channels_awaiting_iso_sent_cb[chan_index] = false;
356355

357-
k_timer_start(&sdu_timer, K_USEC(time_to_next_sdu_us), K_NO_WAIT);
356+
k_work_schedule(&sdu_work, K_USEC(time_to_next_sdu_us));
358357

359358
/* Increment the SDU timestamp with one SDU interval. */
360359
tx_sdu_timestamp_us = assigned_timestamp + CONFIG_SDU_INTERVAL_US;
@@ -369,9 +368,9 @@ static void iso_sent(struct bt_iso_chan *chan)
369368
}
370369
}
371370

372-
static void sdu_timer_expired(struct k_timer *timer)
371+
static void sdu_work_handler(struct k_work *work)
373372
{
374-
ARG_UNUSED(timer);
373+
ARG_UNUSED(work);
375374
send_next_sdu_on_all_channels();
376375
}
377376

0 commit comments

Comments
 (0)