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

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

commit be606bd527bca7441d2b24dcd439ca1698a683b4
Author: wangshaoxin <[email protected]>
AuthorDate: Mon Nov 2 19:13:14 2026 +0800

    drivers/rpmsg: add /proc/rpmsg
    
    Register a procfs entry that lists the local and the remote CPU of
    every registered rpmsg device, so the links a CPU has can be checked
    from the shell:
    
      server> cat /proc/rpmsg
      Local CPU      Remote CPU
      server         proxy
    
    Signed-off-by: wangshaoxin <[email protected]>
    Signed-off-by: Bowen Wang <[email protected]>
---
 drivers/rpmsg/CMakeLists.txt |   4 +
 drivers/rpmsg/Kconfig        |   8 ++
 drivers/rpmsg/Make.defs      |   4 +
 drivers/rpmsg/rpmsg.c        |   2 +
 drivers/rpmsg/rpmsg_procfs.c | 275 +++++++++++++++++++++++++++++++++++++++++++
 drivers/rpmsg/rpmsg_procfs.h |  45 +++++++
 6 files changed, 338 insertions(+)

diff --git a/drivers/rpmsg/CMakeLists.txt b/drivers/rpmsg/CMakeLists.txt
index cc79e76393b..253e6f0f751 100644
--- a/drivers/rpmsg/CMakeLists.txt
+++ b/drivers/rpmsg/CMakeLists.txt
@@ -29,6 +29,10 @@ if(CONFIG_RPMSG)
     list(APPEND SRCS rpmsg_trace.c)
   endif()
 
+  if(CONFIG_RPMSG_PROCFS)
+    list(APPEND SRCS rpmsg_procfs.c)
+  endif()
+
   if(CONFIG_RPMSG_PING)
     list(APPEND SRCS rpmsg_ping.c)
   endif()
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 78a038b1f7b..c299759780a 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -28,6 +28,14 @@ config RPMSG_TRACE_BACKTRACE
                Number of frames recorded with a trace that asks for a
                backtrace. 0 disables backtraces.
 
+config RPMSG_PROCFS
+       bool "Include rpmsg info in procfs"
+       depends on FS_PROCFS_REGISTER
+       default !DEFAULT_SMALL
+       ---help---
+               Add /proc/rpmsg, which lists the local and the remote CPU of 
every
+               registered rpmsg device.
+
 config RPMSG_LOCAL_CPUNAME
        string "Rpmsg Local Cpuname"
        default LIBC_HOSTNAME
diff --git a/drivers/rpmsg/Make.defs b/drivers/rpmsg/Make.defs
index cc43f7834be..fcf1e21265a 100644
--- a/drivers/rpmsg/Make.defs
+++ b/drivers/rpmsg/Make.defs
@@ -30,6 +30,10 @@ ifeq ($(CONFIG_RPMSG_TRACE),y)
 CSRCS += rpmsg_trace.c
 endif
 
+ifeq ($(CONFIG_RPMSG_PROCFS),y)
+CSRCS += rpmsg_procfs.c
+endif
+
 ifeq ($(CONFIG_RPMSG_PING),y)
 CSRCS += rpmsg_ping.c
 endif
diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c
index 54d452e36d1..8cae23497eb 100644
--- a/drivers/rpmsg/rpmsg.c
+++ b/drivers/rpmsg/rpmsg.c
@@ -35,6 +35,7 @@
 #include <nuttx/semaphore.h>
 
 #include "rpmsg.h"
+#include "rpmsg_procfs.h"
 #include "rpmsg_router.h"
 #include "rpmsg_test.h"
 
@@ -167,6 +168,7 @@ static int rpmsg_dev_ioctl(FAR struct file *filep, int cmd,
 
 void rpmsg_initialize(void)
 {
+  rpmsg_procfs_initialize();
 }
 
 int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem)
diff --git a/drivers/rpmsg/rpmsg_procfs.c b/drivers/rpmsg/rpmsg_procfs.c
new file mode 100644
index 00000000000..f7515dc12f9
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_procfs.c
@@ -0,0 +1,275 @@
+/****************************************************************************
+ * drivers/rpmsg/rpmsg_procfs.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <debug.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/fs/procfs.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/nuttx.h>
+#include <nuttx/rpmsg/rpmsg.h>
+
+#include "rpmsg.h"
+#include "rpmsg_procfs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Determines the size of an intermediate buffer that must be large enough
+ * to handle the longest line generated by this logic.
+ */
+
+#define RPMSG_PROCFS_LINELEN 80
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure describes one open "file" */
+
+struct rpmsg_procfs_file_s
+{
+  struct procfs_file_s base;                         /* Base open file 
structure */
+  char                 line[RPMSG_PROCFS_LINELEN];   /* Pre-allocated buffer 
for formatted lines */
+};
+
+struct rpmsg_procfs_info_s
+{
+  FAR struct rpmsg_procfs_file_s *procfile;
+  size_t                          totalsize;
+  FAR char                       *buffer;
+  size_t                          buflen;
+  off_t                           offset;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* File system methods */
+
+static int     rpmsg_procfs_open(FAR struct file *filep,
+                                 FAR const char *relpath,
+                                 int oflags, mode_t mode);
+static int     rpmsg_procfs_close(FAR struct file *filep);
+static ssize_t rpmsg_procfs_read(FAR struct file *filep, FAR char *buffer,
+                                 size_t buflen);
+static int     rpmsg_procfs_dup(FAR const struct file *oldp,
+                                FAR struct file *newp);
+static int     rpmsg_procfs_stat(FAR const char *relpath,
+                                 FAR struct stat *buf);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct procfs_operations g_rpmsg_procfs_ops =
+{
+  rpmsg_procfs_open,   /* open */
+  rpmsg_procfs_close,  /* close */
+  rpmsg_procfs_read,   /* read */
+  NULL,                /* write */
+  NULL,                /* poll */
+
+  rpmsg_procfs_dup,    /* dup */
+
+  NULL,                /* opendir */
+  NULL,                /* closedir */
+  NULL,                /* readdir */
+  NULL,                /* rewinddir */
+
+  rpmsg_procfs_stat,   /* stat */
+};
+
+static const struct procfs_entry_s g_rpmsg_procfs_root =
+{
+  "rpmsg", &g_rpmsg_procfs_ops, PROCFS_FILE_TYPE
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rpmsg_procfs_open
+ ****************************************************************************/
+
+static int rpmsg_procfs_open(FAR struct file *filep, FAR const char *relpath,
+                             int oflags, mode_t mode)
+{
+  FAR struct rpmsg_procfs_file_s *procfile;
+
+  finfo("Open '%s'\n", relpath);
+
+  /* Allocate a container to hold the file attributes */
+
+  procfile = kmm_zalloc(sizeof(struct rpmsg_procfs_file_s));
+  if (procfile == NULL)
+    {
+      rpmsgerr("ERROR: Failed to allocate file attributes\n");
+      return -ENOMEM;
+    }
+
+  /* Save the attributes as the open-specific state in filep->f_priv */
+
+  filep->f_priv = procfile;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: rpmsg_procfs_close
+ ****************************************************************************/
+
+static int rpmsg_procfs_close(FAR struct file *filep)
+{
+  DEBUGASSERT(filep->f_priv);
+
+  /* Release the file attributes structure */
+
+  kmm_free(filep->f_priv);
+  filep->f_priv = NULL;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: rpmsg_procfs_dup
+ ****************************************************************************/
+
+static int rpmsg_procfs_dup(FAR const struct file *oldp,
+                            FAR struct file *newp)
+{
+  FAR struct rpmsg_procfs_file_s *procfile;
+
+  procfile = kmm_zalloc(sizeof(struct rpmsg_procfs_file_s));
+  if (procfile == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  memcpy(procfile, oldp->f_priv, sizeof(struct rpmsg_procfs_file_s));
+  newp->f_priv = procfile;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: rpmsg_procfs_stat
+ ****************************************************************************/
+
+static int rpmsg_procfs_stat(FAR const char *relpath, FAR struct stat *buf)
+{
+  memset(buf, 0, sizeof(struct stat));
+  buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: rpmsg_procfs_handler
+ ****************************************************************************/
+
+static int rpmsg_procfs_handler(FAR struct rpmsg_s *rpmsg, FAR void *args)
+{
+  FAR struct rpmsg_procfs_info_s *procinfo =
+    (FAR struct rpmsg_procfs_info_s *)args;
+  size_t linesize;
+  size_t copysize;
+
+  if (procinfo->buflen > 0)
+    {
+      linesize = procfs_snprintf(procinfo->procfile->line,
+                                 RPMSG_PROCFS_LINELEN,
+                                 "%-15s%-15s\n",
+                                 rpmsg->local_cpuname,
+                                 rpmsg->cpuname);
+      copysize = procfs_memcpy(procinfo->procfile->line, linesize,
+                               procinfo->buffer, procinfo->buflen,
+                               &procinfo->offset);
+      procinfo->totalsize += copysize;
+      procinfo->buffer += copysize;
+      procinfo->buflen -= copysize;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: rpmsg_procfs_read
+ ****************************************************************************/
+
+static ssize_t rpmsg_procfs_read(FAR struct file *filep, FAR char *buffer,
+                                 size_t buflen)
+{
+  FAR struct rpmsg_procfs_info_s procinfo;
+  size_t copysize;
+  size_t linesize;
+
+  procinfo.offset = filep->f_pos;
+  procinfo.procfile = filep->f_priv;
+  linesize = procfs_snprintf(procinfo.procfile->line, RPMSG_PROCFS_LINELEN,
+                             "Local CPU      Remote CPU\n");
+  copysize = procfs_memcpy(procinfo.procfile->line, linesize,
+                           buffer, buflen,
+                           &procinfo.offset);
+
+  buffer += copysize;
+  buflen -= copysize;
+
+  procinfo.totalsize = copysize;
+  procinfo.buffer = buffer;
+  procinfo.buflen = buflen;
+
+  rpmsg_foreach(rpmsg_procfs_handler, &procinfo);
+
+  filep->f_pos += procinfo.totalsize;
+  return procinfo.totalsize;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rpmsg_procfs_initialize
+ ****************************************************************************/
+
+void rpmsg_procfs_initialize(void)
+{
+  int ret;
+
+  ret = procfs_register(&g_rpmsg_procfs_root);
+  if (ret != OK)
+    {
+      rpmsgerr("ERROR: Failed to register rpmsg procfs %d\n", ret);
+    }
+}
diff --git a/drivers/rpmsg/rpmsg_procfs.h b/drivers/rpmsg/rpmsg_procfs.h
new file mode 100644
index 00000000000..d663ecd7e79
--- /dev/null
+++ b/drivers/rpmsg/rpmsg_procfs.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ * drivers/rpmsg/rpmsg_procfs.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_RPMSG_RPMSG_PROCFS_H
+#define __DRIVERS_RPMSG_RPMSG_PROCFS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rpmsg_procfs_initialize
+ ****************************************************************************/
+
+#ifdef CONFIG_RPMSG_PROCFS
+void rpmsg_procfs_initialize(void);
+#else
+#  define rpmsg_procfs_initialize()
+#endif /* CONFIG_RPMSG_PROCFS */
+#endif /* __DRIVERS_RPMSG_RPMSG_PROCFS_H */

Reply via email to