rpmsgdev: add rpmsgdev poll() support.
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
4b6c9915fe
commit
5d8cbfb279
@ -88,6 +88,8 @@ CONFIG_SIM_M32=y
|
||||
CONFIG_SIM_NETDEV=y
|
||||
CONFIG_SIM_NET_BRIDGE=y
|
||||
CONFIG_SIM_RPTUN_MASTER=y
|
||||
CONFIG_SIM_UART0_NAME="/dev/ttyUSB0"
|
||||
CONFIG_SIM_UART_NUMBER=1
|
||||
CONFIG_SYSLOG_PREFIX=y
|
||||
CONFIG_SYSLOG_PREFIX_STRING="server: "
|
||||
CONFIG_SYSLOG_RPMSG_SERVER=y
|
||||
|
@ -440,6 +440,7 @@ int sim_bringup(void)
|
||||
#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");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RPMSGMTD
|
||||
|
@ -25,6 +25,11 @@ config DEV_RPMSG_SERVER
|
||||
default n
|
||||
depends on RPTUN
|
||||
|
||||
config DEV_RPMSG_NPOLLWAITERS
|
||||
int "RPMSG Device Max Number of Poll Threads"
|
||||
default 4
|
||||
depends on DEV_RPMSG_SERVER
|
||||
|
||||
config DRVR_MKRD
|
||||
bool "RAM disk wrapper (mkrd)"
|
||||
default n
|
||||
|
@ -29,7 +29,9 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <limits.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
@ -93,6 +95,8 @@ static off_t rpmsgdev_seek(FAR struct file *filep, off_t offset,
|
||||
static size_t rpmsgdev_ioctl_arglen(int cmd);
|
||||
static int rpmsgdev_ioctl(FAR struct file *filep, int cmd,
|
||||
unsigned long arg);
|
||||
static int rpmsgdev_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup);
|
||||
|
||||
/* Functions for sending data to the remote cpu */
|
||||
|
||||
@ -114,6 +118,9 @@ static int rpmsgdev_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_notify_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
|
||||
/* Functions for creating communication with remote cpu */
|
||||
|
||||
@ -134,12 +141,14 @@ 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_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,
|
||||
};
|
||||
|
||||
/* File operations */
|
||||
@ -152,7 +161,7 @@ const struct file_operations g_rpmsgdev_ops =
|
||||
rpmsgdev_write, /* write */
|
||||
rpmsgdev_seek, /* seek */
|
||||
rpmsgdev_ioctl, /* ioctl */
|
||||
NULL /* poll */
|
||||
rpmsgdev_poll /* poll */
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
, NULL /* unlink */
|
||||
#endif
|
||||
@ -579,6 +588,7 @@ static int rpmsgdev_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
msg = rpmsgdev_get_tx_payload_buffer(dev, &space);
|
||||
if (msg == NULL)
|
||||
{
|
||||
nxmutex_unlock(&dev->excl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -598,6 +608,63 @@ static int rpmsgdev_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_poll
|
||||
*
|
||||
* Description:
|
||||
* Rpmsg-device poll operation
|
||||
*
|
||||
* Parameters:
|
||||
* filep - the file instance
|
||||
* fds - The structure describing the events to be monitored.
|
||||
* setup - true: Setup up the poll; false: Teardown the poll
|
||||
*
|
||||
* Returned Values:
|
||||
* OK on success; A negated errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int rpmsgdev_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
bool setup)
|
||||
{
|
||||
FAR struct rpmsgdev_s *dev;
|
||||
struct rpmsgdev_poll_s msg;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(filep->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
dev = filep->f_inode->i_private;
|
||||
DEBUGASSERT(dev != NULL);
|
||||
|
||||
/* Take the semaphore */
|
||||
|
||||
ret = nxmutex_lock(&dev->excl);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup or teardown the poll */
|
||||
|
||||
msg.events = fds->events;
|
||||
msg.setup = setup;
|
||||
msg.fds = (uint64_t)(uintptr_t)fds;
|
||||
|
||||
ret = rpmsgdev_send_recv(dev, RPMSGDEV_POLL, true, &msg.header,
|
||||
sizeof(msg), NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
rpmsgdeverr("Send failed, ret=%d\n", ret);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&dev->excl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_get_tx_payload_buffer
|
||||
*
|
||||
@ -823,6 +890,37 @@ static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_notify_handler
|
||||
*
|
||||
* Description:
|
||||
* Rpmsg-device poll notify handler.
|
||||
*
|
||||
* Parameters:
|
||||
* ept - The rpmsg endpoint
|
||||
* data - The return message
|
||||
* len - The return message length
|
||||
* src - unknow
|
||||
* priv - unknow
|
||||
*
|
||||
* Returned Values:
|
||||
* Always OK
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int rpmsgdev_notify_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv)
|
||||
{
|
||||
FAR struct rpmsgdev_notify_s *rsp = data;
|
||||
FAR struct pollfd *fds;
|
||||
|
||||
fds = (FAR struct pollfd *)(uintptr_t)rsp->fds;
|
||||
poll_notify(&fds, 1, rsp->revents);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_ns_bound
|
||||
*
|
||||
|
@ -44,6 +44,8 @@
|
||||
#define RPMSGDEV_WRITE 4
|
||||
#define RPMSGDEV_LSEEK 5
|
||||
#define RPMSGDEV_IOCTL 6
|
||||
#define RPMSGDEV_POLL 7
|
||||
#define RPMSGDEV_NOTIFY 8
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -92,6 +94,21 @@ begin_packed_struct struct rpmsgdev_ioctl_s
|
||||
char buf[1];
|
||||
} end_packed_struct;
|
||||
|
||||
begin_packed_struct struct rpmsgdev_poll_s
|
||||
{
|
||||
struct rpmsgdev_header_s header;
|
||||
uint32_t events;
|
||||
uint32_t setup;
|
||||
uint64_t fds;
|
||||
} end_packed_struct;
|
||||
|
||||
begin_packed_struct struct rpmsgdev_notify_s
|
||||
{
|
||||
struct rpmsgdev_header_s header;
|
||||
uint64_t fds;
|
||||
uint32_t revents;
|
||||
} end_packed_struct;
|
||||
|
||||
/****************************************************************************
|
||||
* Internal function prototypes
|
||||
****************************************************************************/
|
||||
|
@ -24,7 +24,9 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
@ -45,6 +47,8 @@ struct rpmsgdev_server_s
|
||||
{
|
||||
struct rpmsg_endpoint ept;
|
||||
struct file file;
|
||||
struct pollfd fds[CONFIG_DEV_RPMSG_NPOLLWAITERS];
|
||||
uint64_t cfds[CONFIG_DEV_RPMSG_NPOLLWAITERS];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -53,22 +57,26 @@ struct rpmsgdev_server_s
|
||||
|
||||
/* Functions handle the messages from the client cpu */
|
||||
|
||||
static int rpmsgdev_open_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_close_handler(FAR struct rpmsg_endpoint *ept,
|
||||
static int rpmsgdev_open_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_write_handler(FAR struct rpmsg_endpoint *ept,
|
||||
static int rpmsgdev_close_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_lseek_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
static int rpmsgdev_write_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_lseek_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
static void rpmsgdev_poll_cb(FAR struct pollfd *fds);
|
||||
static int rpmsgdev_poll_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv);
|
||||
|
||||
@ -97,6 +105,7 @@ static const rpmsg_ept_cb g_rpmsgdev_handler[] =
|
||||
[RPMSGDEV_WRITE] = rpmsgdev_write_handler,
|
||||
[RPMSGDEV_LSEEK] = rpmsgdev_lseek_handler,
|
||||
[RPMSGDEV_IOCTL] = rpmsgdev_ioctl_handler,
|
||||
[RPMSGDEV_POLL] = rpmsgdev_poll_handler,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -251,6 +260,97 @@ static int rpmsgdev_ioctl_handler(FAR struct rpmsg_endpoint *ept,
|
||||
return rpmsg_send(ept, msg, len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_poll_cb
|
||||
****************************************************************************/
|
||||
|
||||
static void rpmsgdev_poll_cb(FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct rpmsgdev_server_s *server = fds->arg;
|
||||
FAR struct rpmsgdev_notify_s msg;
|
||||
int tmp;
|
||||
|
||||
DEBUGASSERT(fds != NULL && (uintptr_t)fds >= (uintptr_t)server->fds);
|
||||
|
||||
tmp = fds - server->fds;
|
||||
|
||||
msg.header.command = RPMSGDEV_NOTIFY;
|
||||
msg.revents = fds->revents;
|
||||
msg.fds = server->cfds[tmp];
|
||||
|
||||
fds->revents = 0;
|
||||
|
||||
rpmsg_send(&server->ept, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_poll_handler
|
||||
****************************************************************************/
|
||||
|
||||
static int rpmsgdev_poll_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR void *data, size_t len,
|
||||
uint32_t src, FAR void *priv)
|
||||
{
|
||||
FAR struct rpmsgdev_server_s *server = ept->priv;
|
||||
FAR struct rpmsgdev_poll_s *msg = data;
|
||||
FAR struct pollfd *fds = NULL;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(msg->fds != 0);
|
||||
|
||||
if (msg->setup)
|
||||
{
|
||||
for (i = 0; i < CONFIG_DEV_RPMSG_NPOLLWAITERS; i++)
|
||||
{
|
||||
if (server->cfds[i] == 0)
|
||||
{
|
||||
server->cfds[i] = msg->fds;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= CONFIG_DEV_RPMSG_NPOLLWAITERS)
|
||||
{
|
||||
msg->header.result = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fds = &server->fds[i];
|
||||
fds->events = msg->events;
|
||||
fds->revents = 0;
|
||||
fds->cb = rpmsgdev_poll_cb;
|
||||
fds->arg = server;
|
||||
|
||||
msg->header.result = file_poll(&server->file, fds, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < CONFIG_DEV_RPMSG_NPOLLWAITERS; i++)
|
||||
{
|
||||
if (server->cfds[i] == msg->fds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= CONFIG_DEV_RPMSG_NPOLLWAITERS)
|
||||
{
|
||||
msg->header.result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fds = &server->fds[i];
|
||||
msg->header.result = file_poll(&server->file, fds, false);
|
||||
if (msg->header.result == OK)
|
||||
{
|
||||
server->cfds[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return rpmsg_send(ept, msg, len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpmsgdev_ns_match
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user