You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/10/08 18:40:12 UTC

[incubator-nuttx] branch master updated: rpmsgdev: add rpmsgdev poll() support.

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 5d8cbfb279 rpmsgdev: add rpmsgdev poll() support.
5d8cbfb279 is described below

commit 5d8cbfb279689466a00a073bb7fc356dd1d47891
Author: wangbowen6 <wa...@xiaomi.com>
AuthorDate: Wed Sep 14 11:09:13 2022 +0800

    rpmsgdev: add rpmsgdev poll() support.
    
    Signed-off-by: wangbowen6 <wa...@xiaomi.com>
---
 boards/sim/sim/sim/configs/rpserver/defconfig |   2 +
 boards/sim/sim/sim/src/sim_bringup.c          |   1 +
 drivers/misc/Kconfig                          |   5 ++
 drivers/misc/rpmsgdev.c                       | 112 +++++++++++++++++++++--
 drivers/misc/rpmsgdev.h                       |  17 ++++
 drivers/misc/rpmsgdev_server.c                | 124 +++++++++++++++++++++++---
 6 files changed, 242 insertions(+), 19 deletions(-)

diff --git a/boards/sim/sim/sim/configs/rpserver/defconfig b/boards/sim/sim/sim/configs/rpserver/defconfig
index 9f633f020c..03170c742b 100644
--- a/boards/sim/sim/sim/configs/rpserver/defconfig
+++ b/boards/sim/sim/sim/configs/rpserver/defconfig
@@ -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
diff --git a/boards/sim/sim/sim/src/sim_bringup.c b/boards/sim/sim/sim/src/sim_bringup.c
index bc37dc57cd..d0b4a099b3 100644
--- a/boards/sim/sim/sim/src/sim_bringup.c
+++ b/boards/sim/sim/sim/src/sim_bringup.c
@@ -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
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 95be70c993..4a9671eb14 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -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
diff --git a/drivers/misc/rpmsgdev.c b/drivers/misc/rpmsgdev.c
index 6d8628334b..75b0bc112d 100644
--- a/drivers/misc/rpmsgdev.c
+++ b/drivers/misc/rpmsgdev.c
@@ -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
  *
diff --git a/drivers/misc/rpmsgdev.h b/drivers/misc/rpmsgdev.h
index f51a7056f0..a92177f5ab 100644
--- a/drivers/misc/rpmsgdev.h
+++ b/drivers/misc/rpmsgdev.h
@@ -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
  ****************************************************************************/
diff --git a/drivers/misc/rpmsgdev_server.c b/drivers/misc/rpmsgdev_server.c
index 6561f8d7f0..20dc0590f8 100644
--- a/drivers/misc/rpmsgdev_server.c
+++ b/drivers/misc/rpmsgdev_server.c
@@ -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,
-                                  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_open_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,
+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_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
  ****************************************************************************/