Skip to content

Commit

Permalink
samples: bluetooth: central_iso: deterministic scheduling
Browse files Browse the repository at this point in the history
The sample used deferred work to schedule ISO SDUs. The deferred work
API does not guarantee deterministic timing, though.

This commit switches to kernel timers which allow for deterministic
periodic or one-off timing as long as timers are re-scheduled in the
timer callback which runs directly in ISR context.

Signed-off-by: Florian Grandel <[email protected]>
  • Loading branch information
Florian Grandel committed May 11, 2024
1 parent faf68d7 commit eb3a6d7
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions samples/bluetooth/central_iso/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@
static void start_scan(void);

static struct bt_conn *default_conn;
static struct k_work_delayable iso_send_work;
static struct bt_iso_chan iso_chan;
static uint32_t seq_num;
NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);

/**
* @brief Send ISO data on timeout
* @brief Send ISO data SDU
*
* This will send an increasing amount of ISO data, starting from 1 octet.
*
Expand All @@ -44,14 +43,16 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
*
* @param work Pointer to the work structure
*/
static void iso_timer_timeout(struct k_work *work)
static void iso_send_sdu(struct k_work *work)
{
static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU];
static size_t len_to_send = 1;
static bool data_initialized;
struct net_buf *buf;
int ret;

ARG_UNUSED(work);

if (!data_initialized) {
for (int i = 0; i < ARRAY_SIZE(buf_data); i++) {
buf_data[i] = (uint8_t)i;
Expand All @@ -72,14 +73,24 @@ static void iso_timer_timeout(struct k_work *work)
net_buf_unref(buf);
}

k_work_schedule(&iso_send_work, K_USEC(INTERVAL_US));

len_to_send++;
if (len_to_send > ARRAY_SIZE(buf_data)) {
len_to_send = 1;
}
}

static K_WORK_DEFINE(iso_send_sdu_work, iso_send_sdu);

static void iso_timer_timeout(struct k_timer *timer)
{
ARG_UNUSED(timer);

k_work_submit(&iso_send_sdu_work);
}

static K_TIMER_DEFINE(iso_timer, iso_timer_timeout, NULL);


static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
Expand Down Expand Up @@ -137,13 +148,13 @@ static void iso_connected(struct bt_iso_chan *chan)
seq_num = 0U;

/* Start send timer */
k_work_schedule(&iso_send_work, K_MSEC(0));
k_timer_start(&iso_timer, K_NO_WAIT, K_USEC(INTERVAL_US));
}

static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
{
printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason);
k_work_cancel_delayable(&iso_send_work);
k_timer_stop(&iso_timer);
}

static struct bt_iso_chan_ops iso_ops = {
Expand Down Expand Up @@ -267,6 +278,5 @@ int main(void)

start_scan();

k_work_init_delayable(&iso_send_work, iso_timer_timeout);
return 0;
}

0 comments on commit eb3a6d7

Please sign in to comment.