32#ifndef ZEPHYR_INCLUDE_RTIO_RTIO_H_
33#define ZEPHYR_INCLUDE_RTIO_RTIO_H_
73#define RTIO_PRIO_LOW 0U
78#define RTIO_PRIO_NORM 127U
83#define RTIO_PRIO_HIGH 255U
100#define RTIO_SQE_CHAINED BIT(0)
143 struct rtio_spsc _spsc;
162 struct rtio_spsc _spsc;
231#ifdef CONFIG_RTIO_SUBMIT_SEM
235 struct k_sem *submit_sem;
240#ifdef CONFIG_RTIO_CONSUME_SEM
245 struct k_sem *consume_sem;
299 struct rtio_spsc _spsc;
380#define RTIO_SQ_DEFINE(name, len) \
381 RTIO_SPSC_DEFINE(name, struct rtio_sqe, len)
389#define RTIO_CQ_DEFINE(name, len) \
390 RTIO_SPSC_DEFINE(name, struct rtio_cqe, len)
399#define RTIO_IODEV_SQ_DEFINE(name, len) \
400 RTIO_SPSC_DEFINE(name, struct rtio_iodev_sqe, len)
410#define RTIO_IODEV_DEFINE(name, iodev_api, qsize, iodev_data) \
411 static RTIO_IODEV_SQ_DEFINE(_iodev_sq_##name, qsize); \
412 const STRUCT_SECTION_ITERABLE(rtio_iodev, name) = { \
413 .api = (iodev_api), \
414 .iodev_sq = (struct rtio_iodev_sq *const)&_iodev_sq_##name, \
415 .data = (iodev_data), \
426#define RTIO_DEFINE(name, exec, sq_sz, cq_sz) \
427 IF_ENABLED(CONFIG_RTIO_SUBMIT_SEM, \
428 (static K_SEM_DEFINE(_submit_sem_##name, 0, K_SEM_MAX_LIMIT))) \
429 IF_ENABLED(CONFIG_RTIO_CONSUME_SEM, \
430 (static K_SEM_DEFINE(_consume_sem_##name, 0, 1))) \
431 static RTIO_SQ_DEFINE(_sq_##name, sq_sz); \
432 static RTIO_CQ_DEFINE(_cq_##name, cq_sz); \
433 STRUCT_SECTION_ITERABLE(rtio, name) = { \
434 .executor = (exec), \
435 .xcqcnt = ATOMIC_INIT(0), \
436 IF_ENABLED(CONFIG_RTIO_SUBMIT_SEM, (.submit_sem = &_submit_sem_##name,)) \
437 IF_ENABLED(CONFIG_RTIO_SUBMIT_SEM, (.submit_count = 0,)) \
438 IF_ENABLED(CONFIG_RTIO_CONSUME_SEM, (.consume_sem = &_consume_sem_##name,)) \
439 .sq = (struct rtio_sq *const)&_sq_##name, \
440 .cq = (struct rtio_cq *const)&_cq_##name, \
540#ifdef CONFIG_RTIO_CONSUME_SEM
545 while (cqe == NULL) {
548#ifdef CONFIG_RTIO_CONSUME_SEM
580 r->executor->api->ok(
r, sqe,
result);
594 r->executor->api->err(
r, sqe,
result);
618#ifdef CONFIG_RTIO_SUBMIT_SEM
619 if (
r->submit_count > 0) {
621 if (
r->submit_count == 0) {
626#ifdef CONFIG_RTIO_CONSUME_SEM
638#ifdef CONFIG_RTIO_SUBMIT_SEM
642#ifdef CONFIG_RTIO_CONSUME_SEM
666static inline int z_impl_rtio_sqe_copy_in(
struct rtio *
r,
673 if (acquirable < sqe_count) {
677 for (
int i = 0; i < sqe_count; i++) {
679 __ASSERT_NO_MSG(sqe != NULL);
707static inline int z_impl_rtio_cqe_copy_out(
struct rtio *
r,
715 for (copied = 0; copied < cqe_count; copied++) {
744static inline int z_impl_rtio_submit(
struct rtio *
r,
uint32_t wait_count)
748 __ASSERT(
r->executor != NULL,
"expected rtio submit context to have an executor");
750#ifdef CONFIG_RTIO_SUBMIT_SEM
753 if (wait_count > 0) {
755 "expected rtio submit with wait count to be called from a thread");
758 r->submit_count = wait_count;
768 res =
r->executor->api->submit(
r);
776#ifdef CONFIG_RTIO_SUBMIT_SEM
778 if (wait_count > 0) {
781 "semaphore was reset or timed out while waiting on completions!");
785#ifdef CONFIG_BOARD_NATIVE_POSIX
804#include <syscalls/rtio.h>
workaround assembler barfing for ST r
Definition: asm-macro-32-bit-gnu.h:24
long atomic_t
Definition: atomic.h:22
atomic_val_t atomic_inc(atomic_t *target)
ZTEST_BMEM int timeout
Definition: main.c:31
struct result result[2]
Definition: errno.c:42
#define K_FOREVER
Generate infinite timeout delay.
Definition: kernel.h:1267
bool k_is_in_isr(void)
Determine if code is running at interrupt level.
static uint32_t rtio_sqe_acquirable(struct rtio *r)
Count of acquirable submission queue events.
Definition: rtio.h:469
static void rtio_sqe_ok(struct rtio *r, const struct rtio_sqe *sqe, int result)
Inform the executor of a submission completion with success.
Definition: rtio.h:578
static void rtio_sqe_prep_nop(struct rtio_sqe *sqe, const struct rtio_iodev *iodev, void *userdata)
Prepare a nop (no op) submission.
Definition: rtio.h:329
static void rtio_sqe_err(struct rtio *r, const struct rtio_sqe *sqe, int result)
Inform the executor of a submissions completion with error.
Definition: rtio.h:592
int rtio_sqe_copy_in(struct rtio *r, const struct rtio_sqe *sqes, size_t sqe_count)
Copy an array of SQEs into the queue.
static void rtio_sqe_prep_read(struct rtio_sqe *sqe, const struct rtio_iodev *iodev, int8_t prio, uint8_t *buf, uint32_t len, void *userdata)
Prepare a read op submission.
Definition: rtio.h:341
static void rtio_cqe_submit(struct rtio *r, int result, void *userdata)
Definition: rtio.h:607
static struct rtio_sqe * rtio_sqe_acquire(struct rtio *r)
Acquire a single submission queue event if available.
Definition: rtio.h:482
#define RTIO_OP_TX
Definition: rtio.h:324
static void rtio_iodev_submit(const struct rtio_sqe *sqe, struct rtio *r)
Perform a submitted operation with an iodev.
Definition: rtio.h:457
static void rtio_sqe_drop_all(struct rtio *r)
Drop all previously acquired sqe.
Definition: rtio.h:503
int rtio_cqe_copy_out(struct rtio *r, struct rtio_cqe *cqes, size_t cqe_count, k_timeout_t timeout)
Copy an array of CQEs from the queue.
static void rtio_access_grant(struct rtio *r, struct k_thread *t)
Definition: rtio.h:634
static void rtio_set_executor(struct rtio *r, struct rtio_executor *exc)
Set the executor of the rtio context.
Definition: rtio.h:446
static void rtio_sqe_prep_write(struct rtio_sqe *sqe, const struct rtio_iodev *iodev, int8_t prio, uint8_t *buf, uint32_t len, void *userdata)
Prepare a write op submission.
Definition: rtio.h:359
static void rtio_cqe_release_all(struct rtio *r)
Release all consumed completion queue events.
Definition: rtio.h:563
#define RTIO_OP_NOP
Definition: rtio.h:318
static struct rtio_cqe * rtio_cqe_consume(struct rtio *r)
Consume a single completion queue event if available.
Definition: rtio.h:520
static struct rtio_cqe * rtio_cqe_consume_block(struct rtio *r)
Wait for and consume a single completion queue event.
Definition: rtio.h:535
static void rtio_sqe_produce_all(struct rtio *r)
Produce all previously acquired sqe.
Definition: rtio.h:492
#define RTIO_OP_RX
Definition: rtio.h:321
int rtio_submit(struct rtio *r, uint32_t wait_count)
Submit I/O requests to the underlying executor.
#define rtio_spsc_consume(spsc)
Consume an element from the spsc.
Definition: rtio_spsc.h:215
#define rtio_spsc_acquire(spsc)
Acquire an element to produce from the SPSC.
Definition: rtio_spsc.h:154
#define rtio_spsc_release_all(spsc)
Release all consumed elements.
Definition: rtio_spsc.h:244
#define rtio_spsc_drop_all(spsc)
Drop all previously acquired elements.
Definition: rtio_spsc.h:203
#define rtio_spsc_consumable(spsc)
Count of consumables in spsc.
Definition: rtio_spsc.h:269
#define rtio_spsc_produce_all(spsc)
Produce all previously acquired elements to the SPSC.
Definition: rtio_spsc.h:187
#define rtio_spsc_acquirable(spsc)
Count of acquirable in spsc.
Definition: rtio_spsc.h:258
#define rtio_spsc_produce(spsc)
Produce one previously acquired element to the SPSC.
Definition: rtio_spsc.h:171
void k_sem_reset(struct k_sem *sem)
Resets a semaphore's count to zero.
void k_sem_give(struct k_sem *sem)
Give a semaphore.
int k_sem_take(struct k_sem *sem, k_timeout_t timeout)
Take a semaphore.
#define ENOMEM
Definition: errno.h:51
void k_yield(void)
Yield the current thread.
void k_busy_wait(uint32_t usec_to_wait)
Cause the current thread to busy wait.
void k_object_access_grant(const void *object, struct k_thread *thread)
struct k_thread t
Definition: kobject.c:1327
A lock-free and type safe power of 2 fixed sized single producer single consumer (SPSC) queue using a...
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__INT32_TYPE__ int32_t
Definition: stdint.h:74
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
__UINT16_TYPE__ uint16_t
Definition: stdint.h:89
__INT8_TYPE__ int8_t
Definition: stdint.h:72
Kernel timeout type.
Definition: sys_clock.h:65
Completion queue.
Definition: rtio.h:161
struct rtio_cqe buffer[]
Definition: rtio.h:163
A completion queue event.
Definition: rtio.h:150
void * userdata
Definition: rtio.h:152
int32_t result
Definition: rtio.h:151
void(* err)(struct rtio *r, const struct rtio_sqe *sqe, int result)
SQE fails to complete.
Definition: rtio.h:187
int(* submit)(struct rtio *r)
Submit the request queue to executor.
Definition: rtio.h:177
void(* ok)(struct rtio *r, const struct rtio_sqe *sqe, int result)
SQE completes successfully.
Definition: rtio.h:182
An executor does the work of executing the submissions.
Definition: rtio.h:210
const struct rtio_executor_api * api
Definition: rtio.h:211
API that an RTIO IO device should implement.
Definition: rtio.h:263
void(* submit)(const struct rtio_sqe *sqe, struct rtio *r)
Submission function for a request to the iodev.
Definition: rtio.h:271
IO device submission queue.
Definition: rtio.h:298
struct rtio_iodev_sqe buffer[]
Definition: rtio.h:300
struct rtio * r
Definition: rtio.h:290
const struct rtio_sqe * sqe
Definition: rtio.h:289
An IO device with a function table for submitting requests.
Definition: rtio.h:306
const struct rtio_iodev_api * api
Definition: rtio.h:308
struct rtio_iodev_sq * iodev_sq
Definition: rtio.h:311
void * data
Definition: rtio.h:314
Submission queue.
Definition: rtio.h:142
struct rtio_sqe buffer[]
Definition: rtio.h:144
A submission queue event.
Definition: rtio.h:109
void * userdata
Definition: rtio.h:125
uint8_t op
Definition: rtio.h:110
uint8_t prio
Definition: rtio.h:112
uint8_t * buf
Definition: rtio.h:131
uint32_t buf_len
Definition: rtio.h:129
const struct rtio_iodev * iodev
Definition: rtio.h:116
uint16_t flags
Definition: rtio.h:114
An RTIO queue pair that both the kernel and application work with.
Definition: rtio.h:222
struct rtio_cq * cq
Definition: rtio.h:257
struct rtio_executor * executor
Definition: rtio.h:228
struct rtio_sq * sq
Definition: rtio.h:254
atomic_t xcqcnt
Definition: rtio.h:251