From 0ead1478417c906c89705046465ee9a1092d4970 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Wed, 14 Jun 2023 12:49:39 +0800 Subject: [PATCH] rpmsgdev: support single read/write mode device The default mode for Rpmsgdev is to read/write data as long as possible for caller, this mode does not apply to tun devices, tun devices can read and write only one complete ip packet at a time. Signed-off-by: zhanghongyu --- boards/sim/sim/sim/src/sim_bringup.c | 6 ++--- drivers/misc/rpmsgdev.c | 39 ++++++++++++++++++++-------- drivers/misc/rpmsgdev.h | 11 ++++---- drivers/misc/rpmsgdev_server.c | 17 ++++++------ include/nuttx/drivers/rpmsgdev.h | 12 ++++++++- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/boards/sim/sim/sim/src/sim_bringup.c b/boards/sim/sim/sim/src/sim_bringup.c index 4f3f31a308..8b8bcd62d6 100644 --- a/boards/sim/sim/sim/src/sim_bringup.c +++ b/boards/sim/sim/sim/src/sim_bringup.c @@ -469,9 +469,9 @@ int sim_bringup(void) #endif #ifdef CONFIG_DEV_RPMSG - rpmsgdev_register("server", "/dev/console", "/dev/server-console"); - rpmsgdev_register("server", "/dev/null", "/dev/server-null"); - rpmsgdev_register("server", "/dev/ttyUSB0", "/dev/ttyUSB0"); + rpmsgdev_register("server", "/dev/console", "/dev/server-console", 0); + rpmsgdev_register("server", "/dev/null", "/dev/server-null", 0); + rpmsgdev_register("server", "/dev/ttyUSB0", "/dev/ttyUSB0", 0); #endif #ifdef CONFIG_BLK_RPMSG diff --git a/drivers/misc/rpmsgdev.c b/drivers/misc/rpmsgdev.c index 3ed43a973c..11f8cb224d 100644 --- a/drivers/misc/rpmsgdev.c +++ b/drivers/misc/rpmsgdev.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "rpmsgdev.h" @@ -69,6 +70,7 @@ struct rpmsgdev_s * opreation until the connection * between two cpu established. */ + uint32_t flags; /* Read and write special handle flags */ }; /* Rpmsg device cookie used to handle the response from the remote cpu */ @@ -145,14 +147,15 @@ static void rpmsgdev_ns_bound(struct rpmsg_endpoint *ept); static const rpmsg_ept_cb g_rpmsgdev_handler[] = { - [RPMSGDEV_OPEN] = rpmsgdev_default_handler, - [RPMSGDEV_CLOSE] = rpmsgdev_default_handler, - [RPMSGDEV_READ] = rpmsgdev_read_handler, - [RPMSGDEV_WRITE] = rpmsgdev_default_handler, - [RPMSGDEV_LSEEK] = rpmsgdev_default_handler, - [RPMSGDEV_IOCTL] = rpmsgdev_ioctl_handler, - [RPMSGDEV_POLL] = rpmsgdev_default_handler, - [RPMSGDEV_NOTIFY] = rpmsgdev_notify_handler, + [RPMSGDEV_OPEN] = rpmsgdev_default_handler, + [RPMSGDEV_CLOSE] = rpmsgdev_default_handler, + [RPMSGDEV_READ] = rpmsgdev_read_handler, + [RPMSGDEV_READ_NOFRAG] = rpmsgdev_read_handler, + [RPMSGDEV_WRITE] = rpmsgdev_default_handler, + [RPMSGDEV_LSEEK] = rpmsgdev_default_handler, + [RPMSGDEV_IOCTL] = rpmsgdev_ioctl_handler, + [RPMSGDEV_POLL] = rpmsgdev_default_handler, + [RPMSGDEV_NOTIFY] = rpmsgdev_notify_handler, }; /* File operations */ @@ -392,6 +395,7 @@ static ssize_t rpmsgdev_read(FAR struct file *filep, FAR char *buffer, FAR struct rpmsgdev_priv_s *priv; struct rpmsgdev_read_s msg; struct iovec read; + uint32_t command; ssize_t ret; if (buffer == NULL) @@ -430,8 +434,10 @@ static ssize_t rpmsgdev_read(FAR struct file *filep, FAR char *buffer, msg.filep = priv->filep; msg.count = buflen; + command = dev->flags & RPMSGDEV_NOFRAG_READ ? + RPMSGDEV_READ_NOFRAG : RPMSGDEV_READ; - ret = rpmsgdev_send_recv(dev, RPMSGDEV_READ, true, &msg.header, + ret = rpmsgdev_send_recv(dev, command, true, &msg.header, sizeof(msg) - 1, &read); return read.iov_len ? read.iov_len : ret; @@ -516,6 +522,12 @@ static ssize_t rpmsgdev_write(FAR struct file *filep, const char *buffer, space = buflen - written; msg->header.cookie = (uintptr_t)&cookie; } + else if ((dev->flags & RPMSGDEV_NOFRAG_WRITE) != 0) + { + rpmsg_release_tx_buffer(&dev->ept, msg); + ret = -EMSGSIZE; + goto out; + } else { /* Not send complete, set cookie invalid, do not need ack */ @@ -928,7 +940,8 @@ static int rpmsgdev_read_handler(FAR struct rpmsg_endpoint *ept, read->iov_len += cookie->result; } - if (cookie->result <= 0 || read->iov_len >= rsp->count) + if (header->command == RPMSGDEV_READ_NOFRAG || + cookie->result <= 0 || read->iov_len >= rsp->count) { rpmsg_post(ept, &cookie->sem); } @@ -1139,6 +1152,9 @@ static int rpmsgdev_ept_cb(FAR struct rpmsg_endpoint *ept, * localpath - the device path in local cpu, if NULL, the localpath is * same as the remotepath, provide this argument to supoort * custom device path + * flags - RPMSGDEV_NOFRAG_READ and RPMSGDEV_NOFRAG_WRITE can be set + * to indicates that the read and write data of the device + * cannot be split or aggregated * * Returned Values: * OK on success; A negated errno value is returned on any failure. @@ -1146,7 +1162,7 @@ static int rpmsgdev_ept_cb(FAR struct rpmsg_endpoint *ept, ****************************************************************************/ int rpmsgdev_register(FAR const char *remotecpu, FAR const char *remotepath, - FAR const char *localpath) + FAR const char *localpath, uint32_t flags) { FAR struct rpmsgdev_s *dev; int ret; @@ -1168,6 +1184,7 @@ int rpmsgdev_register(FAR const char *remotecpu, FAR const char *remotepath, dev->remotecpu = remotecpu; dev->remotepath = remotepath; + dev->flags = flags; nxsem_init(&dev->wait, 0, 0); diff --git a/drivers/misc/rpmsgdev.h b/drivers/misc/rpmsgdev.h index a276612df3..f0254f1534 100644 --- a/drivers/misc/rpmsgdev.h +++ b/drivers/misc/rpmsgdev.h @@ -39,11 +39,12 @@ #define RPMSGDEV_OPEN 1 #define RPMSGDEV_CLOSE 2 #define RPMSGDEV_READ 3 -#define RPMSGDEV_WRITE 4 -#define RPMSGDEV_LSEEK 5 -#define RPMSGDEV_IOCTL 6 -#define RPMSGDEV_POLL 7 -#define RPMSGDEV_NOTIFY 8 +#define RPMSGDEV_READ_NOFRAG 4 +#define RPMSGDEV_WRITE 5 +#define RPMSGDEV_LSEEK 6 +#define RPMSGDEV_IOCTL 7 +#define RPMSGDEV_POLL 8 +#define RPMSGDEV_NOTIFY 9 /**************************************************************************** * Public Types diff --git a/drivers/misc/rpmsgdev_server.c b/drivers/misc/rpmsgdev_server.c index a65c7a2c56..856db037ec 100644 --- a/drivers/misc/rpmsgdev_server.c +++ b/drivers/misc/rpmsgdev_server.c @@ -115,13 +115,14 @@ static int rpmsgdev_ept_cb(FAR struct rpmsg_endpoint *ept, static const rpmsg_ept_cb g_rpmsgdev_handler[] = { - [RPMSGDEV_OPEN] = rpmsgdev_open_handler, - [RPMSGDEV_CLOSE] = rpmsgdev_close_handler, - [RPMSGDEV_READ] = rpmsgdev_read_handler, - [RPMSGDEV_WRITE] = rpmsgdev_write_handler, - [RPMSGDEV_LSEEK] = rpmsgdev_lseek_handler, - [RPMSGDEV_IOCTL] = rpmsgdev_ioctl_handler, - [RPMSGDEV_POLL] = rpmsgdev_poll_handler, + [RPMSGDEV_OPEN] = rpmsgdev_open_handler, + [RPMSGDEV_CLOSE] = rpmsgdev_close_handler, + [RPMSGDEV_READ] = rpmsgdev_read_handler, + [RPMSGDEV_READ_NOFRAG] = rpmsgdev_read_handler, + [RPMSGDEV_WRITE] = rpmsgdev_write_handler, + [RPMSGDEV_LSEEK] = rpmsgdev_lseek_handler, + [RPMSGDEV_IOCTL] = rpmsgdev_ioctl_handler, + [RPMSGDEV_POLL] = rpmsgdev_poll_handler, }; /**************************************************************************** @@ -227,7 +228,7 @@ static int rpmsgdev_read_handler(FAR struct rpmsg_endpoint *ept, rsp->header.result = ret; rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp) - 1); - if (ret <= 0) + if (ret <= 0 || msg->header.command == RPMSGDEV_READ_NOFRAG) { break; } diff --git a/include/nuttx/drivers/rpmsgdev.h b/include/nuttx/drivers/rpmsgdev.h index e3d86f2160..7ddeb95cc9 100644 --- a/include/nuttx/drivers/rpmsgdev.h +++ b/include/nuttx/drivers/rpmsgdev.h @@ -27,6 +27,13 @@ #include +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +#define RPMSGDEV_NOFRAG_READ 0x1 +#define RPMSGDEV_NOFRAG_WRITE 0x2 + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -71,6 +78,9 @@ int rpmsgdev_server_init(void); * localpath - the device path in local cpu, if NULL, the localpath is * same as the remotepath, provide this argument to supoort * custom device path + * flags - RPMSGDEV_NOFRAG_READ and RPMSGDEV_NOFRAG_WRITE can be set + * to indicates that the read and write data of the device + * cannot be split or aggregated * * Returned Values: * OK on success; A negated errno value is returned on any failure. @@ -79,7 +89,7 @@ int rpmsgdev_server_init(void); #ifdef CONFIG_DEV_RPMSG int rpmsgdev_register(FAR const char *remotecpu, FAR const char *remotepath, - FAR const char *localpath); + FAR const char *localpath, uint32_t flags); #endif #undef EXTERN