Skip to content

Commit e7506b0

Browse files
committed
rtio: Introduce OP_DELAY as a valid SQE operation
SQE items with this OP will take the specified amount of time (asynchronously) before completing. This allows to serve as an asynchronous delay in between SQE items (e.g: A sensor measurement requested, which requires 50-ms before having the result available). Signed-off-by: Luis Ubieda <[email protected]>
1 parent 8661c3c commit e7506b0

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

include/zephyr/rtio/rtio.h

+23-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <zephyr/app_memory/app_memdomain.h>
3232
#include <zephyr/device.h>
3333
#include <zephyr/kernel.h>
34+
#include <zephyr/kernel_structs.h>
3435
#include <zephyr/sys/__assert.h>
3536
#include <zephyr/sys/atomic.h>
3637
#include <zephyr/sys/mem_blocks.h>
@@ -344,6 +345,12 @@ struct rtio_sqe {
344345
uint8_t *rx_buf; /**< Buffer to read into */
345346
} txrx;
346347

348+
/** OP_DELAY */
349+
struct {
350+
k_timeout_t timeout; /**< Delay timeout. */
351+
struct _timeout to; /**< Timeout struct. Used internally. */
352+
} delay;
353+
347354
/** OP_I2C_CONFIGURE */
348355
uint32_t i2c_config;
349356

@@ -555,8 +562,11 @@ struct rtio_iodev {
555562
/** An operation that transceives (reads and writes simultaneously) */
556563
#define RTIO_OP_TXRX (RTIO_OP_CALLBACK+1)
557564

565+
/** An operation that takes a specified amount of time (asynchronously) before completing */
566+
#define RTIO_OP_DELAY (RTIO_OP_TXRX+1)
567+
558568
/** An operation to recover I2C buses */
559-
#define RTIO_OP_I2C_RECOVER (RTIO_OP_TXRX+1)
569+
#define RTIO_OP_I2C_RECOVER (RTIO_OP_DELAY+1)
560570

561571
/** An operation to configure I2C buses */
562572
#define RTIO_OP_I2C_CONFIGURE (RTIO_OP_I2C_RECOVER+1)
@@ -747,6 +757,18 @@ static inline void rtio_sqe_prep_await(struct rtio_sqe *sqe,
747757
sqe->userdata = userdata;
748758
}
749759

760+
static inline void rtio_sqe_prep_delay(struct rtio_sqe *sqe,
761+
k_timeout_t timeout,
762+
void *userdata)
763+
{
764+
memset(sqe, 0, sizeof(struct rtio_sqe));
765+
sqe->op = RTIO_OP_DELAY;
766+
sqe->prio = 0;
767+
sqe->iodev = NULL;
768+
sqe->delay.timeout = timeout;
769+
sqe->userdata = userdata;
770+
}
771+
750772
static inline struct rtio_iodev_sqe *rtio_sqe_pool_alloc(struct rtio_sqe_pool *pool)
751773
{
752774
struct mpsc_node *node = mpsc_pop(&pool->free_q);

subsys/rtio/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ if(CONFIG_RTIO)
1010

1111
zephyr_library_sources(rtio_executor.c)
1212
zephyr_library_sources(rtio_init.c)
13+
zephyr_library_sources(rtio_sched.c)
1314
zephyr_library_sources_ifdef(CONFIG_USERSPACE rtio_handlers.c)
1415
endif()
1516

subsys/rtio/rtio_executor.c

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <zephyr/rtio/rtio.h>
88
#include <zephyr/kernel.h>
99

10+
#include "rtio_sched.h"
11+
1012
#include <zephyr/logging/log.h>
1113
LOG_MODULE_REGISTER(rtio_executor, CONFIG_RTIO_LOG_LEVEL);
1214

@@ -22,6 +24,9 @@ static void rtio_executor_op(struct rtio_iodev_sqe *iodev_sqe)
2224
sqe->callback.callback(iodev_sqe->r, sqe, sqe->callback.arg0);
2325
rtio_iodev_sqe_ok(iodev_sqe, 0);
2426
break;
27+
case RTIO_OP_DELAY:
28+
rtio_sched_alarm(iodev_sqe, sqe->delay.timeout);
29+
break;
2530
default:
2631
rtio_iodev_sqe_err(iodev_sqe, -EINVAL);
2732
}

subsys/rtio/rtio_sched.c

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2025 Croxel Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/rtio/rtio.h>
9+
10+
/** Required to access Timeout Queue APIs, which are used instead of the
11+
* Timer APIs because of concerns on size on rtio_sqe (k_timer is more
12+
* than double the size of _timeout). Users will have to instantiate a
13+
* pool of SQE objects, thus its size directly impacts memory footprint
14+
* of RTIO applications.
15+
*/
16+
#include <../kernel/include/timeout_q.h>
17+
18+
#include "rtio_sched.h"
19+
20+
static void rtio_sched_alarm_expired(struct _timeout *t)
21+
{
22+
struct rtio_sqe *sqe = CONTAINER_OF(t, struct rtio_sqe, delay.to);
23+
struct rtio_iodev_sqe *iodev_sqe = CONTAINER_OF(sqe, struct rtio_iodev_sqe, sqe);
24+
25+
rtio_iodev_sqe_ok(iodev_sqe, 0);
26+
}
27+
28+
void rtio_sched_alarm(struct rtio_iodev_sqe *iodev_sqe, k_timeout_t timeout)
29+
{
30+
struct rtio_sqe *sqe = &iodev_sqe->sqe;
31+
32+
z_init_timeout(&sqe->delay.to);
33+
z_add_timeout(&sqe->delay.to, rtio_sched_alarm_expired, timeout);
34+
}

subsys/rtio/rtio_sched.h

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2025 Croxel Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
9+
#ifndef ZEPHYR_SUBSYS_RTIO_SCHED_H_
10+
#define ZEPHYR_SUBSYS_RTIO_SCHED_H_
11+
12+
void rtio_sched_alarm(struct rtio_iodev_sqe *iodev_sqe, k_timeout_t timeout);
13+
14+
#endif /* ZEPHYR_SUBSYS_RTIO_SCHED_H_ */

0 commit comments

Comments
 (0)