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 <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2023-06-14 12:49:39 +08:00 committed by Xiang Xiao
parent 2b4cf41e14
commit 0ead147841
5 changed files with 57 additions and 28 deletions

View file

@ -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

View file

@ -39,6 +39,7 @@
#include <nuttx/video/fb.h>
#include <nuttx/mutex.h>
#include <nuttx/rptun/openamp.h>
#include <nuttx/drivers/rpmsgdev.h>
#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);

View file

@ -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

View file

@ -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;
}

View file

@ -27,6 +27,13 @@
#include <nuttx/config.h>
/****************************************************************************
* 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