Skip to content

Commit 1b54c9c

Browse files
committed
rtio: Add tiny write op
When sending small buffers out it makes sense to copy rather than reference to avoid having to keep the small buffer around for the lifetime of the write request. Adjusts the op numbers to always be +1 from the previously defined op id making it easier to re-arrange if needed in the future. Signed-off-by: Tom Burdick <[email protected]>
1 parent 3024bc5 commit 1b54c9c

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

include/zephyr/rtio/rtio.h

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <zephyr/sys/atomic.h>
3939
#include <zephyr/device.h>
4040
#include <zephyr/kernel.h>
41+
#include <string.h>
4142

4243
#ifdef __cplusplus
4344
extern "C" {
@@ -133,20 +134,34 @@ struct rtio_sqe {
133134
const struct rtio_iodev *iodev; /**< Device to operation on */
134135

135136
/**
136-
* User provided pointer to data which is returned upon operation
137-
* completion
137+
* User provided data which is returned upon operation
138+
* completion. Could be a pointer or integer.
138139
*
139140
* If unique identification of completions is desired this should be
140141
* unique as well.
141142
*/
142143
void *userdata;
143144

144145
union {
146+
147+
/** OP_TX, OP_RX */
145148
struct {
146149
uint32_t buf_len; /**< Length of buffer */
147150

148151
uint8_t *buf; /**< Buffer to use*/
149152
};
153+
154+
/** OP_TINY_TX */
155+
struct {
156+
uint8_t tiny_buf_len; /**< Length of tiny buffer */
157+
uint8_t tiny_buf[7]; /**< Tiny buffer */
158+
};
159+
160+
/** OP_CALLBACK */
161+
struct {
162+
void (*callback)(struct rtio *r, struct rtio_sqe *sqe, void *arg0);
163+
void *arg0;
164+
};
150165
};
151166
};
152167

@@ -321,10 +336,17 @@ struct rtio_iodev {
321336
#define RTIO_OP_NOP 0
322337

323338
/** An operation that receives (reads) */
324-
#define RTIO_OP_RX 1
339+
#define RTIO_OP_RX (RTIO_OP_NOP+1)
325340

326341
/** An operation that transmits (writes) */
327-
#define RTIO_OP_TX 2
342+
#define RTIO_OP_TX (RTIO_OP_RX+1)
343+
344+
/** An operation that transmits tiny writes */
345+
#define RTIO_OP_TINY_TX (RTIO_OP_TX+1)
346+
347+
/** An operation that does some small functional work */
348+
#define RTIO_OP_FUNC (RTIO_OP_TINY_TX+1)
349+
328350

329351
/**
330352
* @brief Prepare a nop (no op) submission
@@ -377,6 +399,34 @@ static inline void rtio_sqe_prep_write(struct rtio_sqe *sqe,
377399
sqe->userdata = userdata;
378400
}
379401

402+
/**
403+
* @brief Prepare a tiny write op submission
404+
*
405+
* Unlike the normal write operation where the source buffer must outlive the call
406+
* the tiny write data in this case is copied to the sqe. It must be tiny to fit
407+
* within the specified size of a rtio_sqe.
408+
*
409+
* This is useful in many scenarios with RTL logic where a write of the register to
410+
* subsequently read must be done.
411+
*/
412+
static inline void rtio_sqe_prep_tiny_write(struct rtio_sqe *sqe,
413+
const struct rtio_iodev *iodev,
414+
int8_t prio,
415+
const uint8_t *tiny_write_data,
416+
uint8_t tiny_write_len,
417+
void *userdata)
418+
{
419+
__ASSERT_NO_MSG(tiny_write_len <= sizeof(sqe->tiny_buf));
420+
421+
sqe->op = RTIO_OP_TINY_TX;
422+
sqe->prio = prio;
423+
sqe->flags = 0;
424+
sqe->iodev = iodev;
425+
sqe->tiny_buf_len = tiny_write_len;
426+
memcpy(sqe->tiny_buf, tiny_write_data, tiny_write_len);
427+
sqe->userdata = userdata;
428+
}
429+
380430
/**
381431
* @brief Statically define and initialize a fixed length submission queue.
382432
*

subsys/rtio/rtio_handlers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ static inline bool rtio_vrfy_sqe(struct rtio_sqe *sqe)
3131
case RTIO_OP_RX:
3232
valid_sqe &= Z_SYSCALL_MEMORY(sqe->buf, sqe->buf_len, true);
3333
break;
34+
case RTIO_OP_TINY_TX:
35+
break;
3436
default:
3537
/* RTIO OP must be known */
3638
valid_sqe = false;

0 commit comments

Comments
 (0)