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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 869271f5b8 drivers/note: suport rpmsg transfer channel for note,some 
note api need to adapte for rpmsg.
869271f5b8 is described below

commit 869271f5b89ee09e746a4084c56ef2f0184e209c
Author: zhangwenjian <[email protected]>
AuthorDate: Tue Jan 30 18:57:36 2024 +0800

    drivers/note: suport rpmsg transfer channel for note,some note api
    need to adapte for rpmsg.
    
    We can transfer note content through rpmsg
    
    Signed-off-by: zhangwenjian <[email protected]>
---
 drivers/note/CMakeLists.txt     |   8 ++
 drivers/note/Kconfig            |  36 +++++
 drivers/note/Make.defs          |   8 ++
 drivers/note/note_driver.c      |   4 +
 drivers/note/note_initialize.c  |  20 +++
 drivers/note/noterpmsg.h        |  56 ++++++++
 drivers/note/noterpmsg_driver.c | 286 ++++++++++++++++++++++++++++++++++++++++
 drivers/note/noterpmsg_server.c | 129 ++++++++++++++++++
 8 files changed, 547 insertions(+)

diff --git a/drivers/note/CMakeLists.txt b/drivers/note/CMakeLists.txt
index e2651cd981..ff3807bcae 100644
--- a/drivers/note/CMakeLists.txt
+++ b/drivers/note/CMakeLists.txt
@@ -40,5 +40,13 @@ if(CONFIG_DRIVERS_NOTESNAP)
   list(APPEND SRCS notesnap_driver.c)
 endif()
 
+if(CONFIG_DRIVERS_NOTERPMSG_SERVER)
+  list(APPEND SRCS noterpmsg_server.c)
+endif()
+
+if(CONFIG_DRIVERS_NOTERPMSG)
+  list(APPEND SRCS noterpmsg_driver.c)
+endif()
+
 target_sources(drivers PRIVATE ${SRCS})
 target_include_directories(drivers PRIVATE ${NUTTX_DIR}/sched)
diff --git a/drivers/note/Kconfig b/drivers/note/Kconfig
index 49248bd121..a9b296862d 100644
--- a/drivers/note/Kconfig
+++ b/drivers/note/Kconfig
@@ -106,4 +106,40 @@ config DRIVERS_NOTESNAP_NBUFFERS
                Number of last scheduling information buffers.
 endif
 
+config DRIVERS_NOTERPMSG_SERVER
+       bool "Enable RPMSG server for NOTE"
+       default n
+       depends on RPTUN
+       ---help---
+               Use rpmsg to receive message from remote proc.
+
+config DRIVERS_NOTERPMSG
+       bool "Note to RPMSG"
+       depends on RPTUN
+       depends on SCHED_WORKQUEUE
+       default n
+       ---help---
+               Use the rpmsg as a Note output device, send message to remote 
proc.
+
+if DRIVERS_NOTERPMSG
+
+config DRIVERS_NOTERPMSG_BUFSIZE
+       int "Note RPMSG client buffer size"
+       default 1024
+       ---help---
+               The size of the client buffer (in bytes)
+
+config DRIVERS_NOTERPMSG_SERVER_NAME
+       string "The name of Note Rpmsg Server"
+       default "ap"
+       ---help---
+               The proc name of rpmsg server. Client sends message to
+               specified name of remote proc.
+
+config DRIVERS_NOTERPMSG_WORK_DELAY
+       int "NOTE RPMSG work delay(ms)"
+       default 100
+
+endif
+
 endif # DRIVERS_NOTE
diff --git a/drivers/note/Make.defs b/drivers/note/Make.defs
index 096063aa42..02a14ee1c9 100644
--- a/drivers/note/Make.defs
+++ b/drivers/note/Make.defs
@@ -41,5 +41,13 @@ ifeq ($(CONFIG_DRIVERS_NOTESNAP),y)
   CSRCS += notesnap_driver.c
 endif
 
+ifeq ($(CONFIG_DRIVERS_NOTERPMSG_SERVER),y)
+  CSRCS += noterpmsg_server.c
+endif
+
+ifeq ($(CONFIG_DRIVERS_NOTERPMSG),y)
+  CSRCS += noterpmsg_driver.c
+endif
+
 DEPPATH += --dep-path note
 VPATH += :note
diff --git a/drivers/note/note_driver.c b/drivers/note/note_driver.c
index 7414166542..25ae513dec 100644
--- a/drivers/note/note_driver.c
+++ b/drivers/note/note_driver.c
@@ -43,6 +43,7 @@
 #include <nuttx/instrument.h>
 
 #include "sched/sched.h"
+#include "noterpmsg.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -193,6 +194,9 @@ FAR static struct note_driver_s *
 #endif
 #ifdef CONFIG_DRIVERS_NOTELOG
   &g_notelog_driver,
+#endif
+#ifdef CONFIG_DRIVERS_NOTERPMSG
+  (FAR struct note_driver_s *)&g_noterpmsg_driver,
 #endif
   NULL
 };
diff --git a/drivers/note/note_initialize.c b/drivers/note/note_initialize.c
index 5d50728925..475dafa444 100644
--- a/drivers/note/note_initialize.c
+++ b/drivers/note/note_initialize.c
@@ -31,6 +31,8 @@
 #include <nuttx/segger/note_rtt.h>
 #include <nuttx/segger/sysview.h>
 
+#include "noterpmsg.h"
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -121,5 +123,23 @@ int note_initialize(void)
     }
 #endif
 
+#ifdef CONFIG_DRIVERS_NOTERPMSG_SERVER
+  ret = noterpmsg_server_init();
+  if (ret < 0)
+    {
+      serr("noterpmsg_server_init failed %d\n", ret);
+      return ret;
+    }
+#endif
+
+#ifdef CONFIG_DRIVERS_NOTERPMSG
+  ret = noterpmsg_init();
+  if (ret < 0)
+    {
+      serr("noterpmsg_init failed %d\n", ret);
+      return ret;
+    }
+#endif
+
   return ret;
 }
diff --git a/drivers/note/noterpmsg.h b/drivers/note/noterpmsg.h
new file mode 100644
index 0000000000..3eb2af1ed0
--- /dev/null
+++ b/drivers/note/noterpmsg.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * drivers/note/noterpmsg.h
+ *
+ * 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_NOTE_NOTERPMSG_H
+#define __DRIVERS_NOTE_NOTERPMSG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+#define NOTERPMSG_EPT_NAME           "rpmsg-note"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef CONFIG_DRIVERS_NOTERPMSG
+extern struct noterpmsg_driver_s g_noterpmsg_driver;
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_DRIVERS_NOTERPMSG_SERVER
+int noterpmsg_server_init(void);
+#endif
+
+#ifdef CONFIG_DRIVERS_NOTERPMSG
+int noterpmsg_init(void);
+#endif
+
+#endif /* __DRIVERS_NOTE_NOTERPMSG_H */
diff --git a/drivers/note/noterpmsg_driver.c b/drivers/note/noterpmsg_driver.c
new file mode 100644
index 0000000000..67fbbcc9d4
--- /dev/null
+++ b/drivers/note/noterpmsg_driver.c
@@ -0,0 +1,286 @@
+/****************************************************************************
+ * drivers/note/noterpmsg_driver.c
+ *
+ * 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/note/note_driver.h>
+#include <nuttx/rpmsg/rpmsg.h>
+#include <nuttx/sched_note.h>
+#include <nuttx/wqueue.h>
+
+#include "noterpmsg.h"
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+#define NOTE_RPMSG_WORK_DELAY MSEC2TICK(CONFIG_DRIVERS_NOTERPMSG_WORK_DELAY)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct noterpmsg_driver_s
+{
+  struct note_driver_s  driver;
+  volatile size_t       head;
+  volatile size_t       tail;
+  uint8_t               buffer[CONFIG_DRIVERS_NOTERPMSG_BUFSIZE];
+  struct work_s         work;
+  struct rpmsg_endpoint ept;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void noterpmsg_add(FAR struct note_driver_s *driver,
+                          FAR const void *note, size_t notelen);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct note_driver_ops_s g_noterpmsg_ops =
+{
+  noterpmsg_add
+};
+
+struct noterpmsg_driver_s g_noterpmsg_driver =
+{
+  {&g_noterpmsg_ops},
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline size_t noterpmsg_next(FAR struct noterpmsg_driver_s *drv,
+                                    size_t pos, size_t offset)
+{
+  pos += offset;
+  if (pos >= CONFIG_DRIVERS_NOTERPMSG_BUFSIZE)
+    {
+      pos -= CONFIG_DRIVERS_NOTERPMSG_BUFSIZE;
+    }
+
+  return pos;
+}
+
+static inline size_t noterpmsg_length(FAR struct noterpmsg_driver_s *drv)
+{
+  size_t head = drv->head;
+  size_t tail = drv->tail;
+
+  if (tail > head)
+    {
+      head += CONFIG_DRIVERS_NOTERPMSG_BUFSIZE;
+    }
+
+  return head - tail;
+}
+
+static inline void noterpmsg_remove(FAR struct noterpmsg_driver_s *drv)
+{
+  size_t tail = drv->tail;
+  uint8_t notelen = drv->buffer[tail];
+
+  DEBUGASSERT(notelen <= noterpmsg_length(drv));
+  drv->tail = noterpmsg_next(drv, tail, notelen);
+}
+
+static bool noterpmsg_transfer(FAR struct noterpmsg_driver_s *drv,
+                               bool wait)
+{
+  for (; ; )
+    {
+      FAR uint8_t *buffer;
+      uint32_t space;
+      size_t len;
+
+      len = noterpmsg_length(drv);
+      if (len == 0)
+        {
+          return true;
+        }
+
+      buffer = rpmsg_get_tx_payload_buffer(&drv->ept, &space, wait);
+      if (buffer == NULL)
+        {
+          return false;
+        }
+
+      if (space < len)
+        {
+          /* Find the len of large entire note data */
+
+          size_t pos = drv->tail;
+          uint8_t notelen = drv->buffer[pos];
+
+          len = 0;
+          while (len + notelen <= space)
+            {
+              pos = noterpmsg_next(drv, pos, notelen);
+              len += notelen;
+              notelen = drv->buffer[pos];
+            }
+        }
+
+      space = CONFIG_DRIVERS_NOTERPMSG_BUFSIZE - drv->tail;
+      space = space < len ? space : len;
+
+      memcpy(buffer, drv->buffer + drv->tail, space);
+      memcpy(buffer + space, drv->buffer, len - space);
+
+      rpmsg_send_nocopy(&drv->ept, buffer, len);
+      drv->tail = noterpmsg_next(drv, drv->tail, len);
+    }
+}
+
+static void noterpmsg_work(FAR void *priv)
+{
+  FAR struct noterpmsg_driver_s *drv = priv;
+  irqstate_t flags = enter_critical_section();
+
+  if (!noterpmsg_transfer(drv, false))
+    {
+      work_queue(HPWORK, &drv->work, noterpmsg_work, drv,
+                 NOTE_RPMSG_WORK_DELAY);
+    }
+
+  leave_critical_section(flags);
+}
+
+static void noterpmsg_add(FAR struct note_driver_s *driver,
+                          FAR const void *note, size_t notelen)
+{
+  FAR struct noterpmsg_driver_s *drv =
+    (FAR struct noterpmsg_driver_s *)driver;
+  irqstate_t flags;
+  size_t space;
+
+  flags = enter_critical_section();
+
+  space = CONFIG_DRIVERS_NOTERPMSG_BUFSIZE - noterpmsg_length(drv);
+  if (space < notelen)
+    {
+      if (!up_interrupt_context() && !sched_idletask())
+        {
+          noterpmsg_transfer(drv, true);
+        }
+      else
+        {
+          /* Overwrite */
+
+          do
+            {
+              noterpmsg_remove(drv);
+              space = CONFIG_DRIVERS_NOTERPMSG_BUFSIZE -
+                      noterpmsg_length(drv);
+            }
+          while (space < notelen);
+        }
+    }
+
+  space = CONFIG_DRIVERS_NOTERPMSG_BUFSIZE - drv->head;
+  space = space < notelen ? space : notelen;
+
+  memcpy(drv->buffer + drv->head, note, space);
+  memcpy(drv->buffer, note + space, notelen - space);
+
+  drv->head = noterpmsg_next(drv, drv->head, notelen);
+
+  if (work_available(&drv->work))
+    {
+      work_queue(HPWORK, &drv->work, noterpmsg_work, drv,
+                 NOTE_RPMSG_WORK_DELAY);
+    }
+
+  leave_critical_section(flags);
+}
+
+static int noterpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
+                            FAR void *data, size_t len, uint32_t src,
+                            FAR void *priv)
+{
+  return 0;
+}
+
+static void noterpmsg_device_created(FAR struct rpmsg_device *rdev,
+                                     FAR void *priv)
+{
+  FAR struct noterpmsg_driver_s *drv = priv;
+  int ret;
+
+  if (strcmp(CONFIG_DRIVERS_NOTERPMSG_SERVER_NAME,
+             rpmsg_get_cpuname(rdev)) == 0)
+    {
+      drv->ept.priv = drv;
+
+      ret = rpmsg_create_ept(&drv->ept, rdev, NOTERPMSG_EPT_NAME,
+                             RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                             noterpmsg_ept_cb, NULL);
+      if (ret >= 0)
+        {
+          work_queue(HPWORK, &drv->work, noterpmsg_work, drv, 0);
+        }
+    }
+}
+
+static void noterpmsg_device_destroy(FAR struct rpmsg_device *rdev,
+                                     FAR void *priv)
+{
+  FAR struct noterpmsg_driver_s *drv = priv;
+
+  if (strcmp(CONFIG_DRIVERS_NOTERPMSG_SERVER_NAME,
+             rpmsg_get_cpuname(rdev)) == 0)
+    {
+      rpmsg_destroy_ept(&drv->ept);
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: noterpmsg_init
+ *
+ * Description:
+ *   Register a rmpsg channel to note.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero on success. A negated errno value is returned on a failure.
+ *
+ ****************************************************************************/
+
+int noterpmsg_init(void)
+{
+  return rpmsg_register_callback(&g_noterpmsg_driver,
+                                 noterpmsg_device_created,
+                                 noterpmsg_device_destroy,
+                                 NULL,
+                                 NULL);
+}
diff --git a/drivers/note/noterpmsg_server.c b/drivers/note/noterpmsg_server.c
new file mode 100644
index 0000000000..43e4f6ac57
--- /dev/null
+++ b/drivers/note/noterpmsg_server.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * drivers/note/noterpmsg_server.c
+ *
+ * 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/kmalloc.h>
+#include <nuttx/rpmsg/rpmsg.h>
+#include <nuttx/sched_note.h>
+
+#include "noterpmsg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct noterpmsg_server_s
+{
+  struct rpmsg_endpoint ept;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int noterpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
+                            FAR void *data, size_t len,
+                            uint32_t src, FAR void *priv)
+{
+  /* The client ensures that the packet sent is the correct note
+   * data packet.
+   */
+
+  sched_note_add(data, len);
+
+  return 0;
+}
+
+static void noterpmsg_ns_unbind(FAR struct rpmsg_endpoint *ept)
+{
+  FAR struct noterpmsg_server_s *srv = ept->priv;
+
+  rpmsg_destroy_ept(ept);
+  kmm_free(srv);
+}
+
+static bool noterpmsg_ns_match(FAR struct rpmsg_device *rdev,
+                               FAR void *priv, FAR const char *name,
+                               uint32_t dest)
+{
+  return !strcmp(name, NOTERPMSG_EPT_NAME);
+}
+
+static void noterpmsg_ns_bind(FAR struct rpmsg_device *rdev,
+                              FAR void *priv, FAR const char *name,
+                              uint32_t dest)
+{
+  FAR struct noterpmsg_server_s *srv;
+  int ret;
+
+  srv = kmm_zalloc(sizeof(struct noterpmsg_server_s));
+  if (srv == NULL)
+    {
+      return;
+    }
+
+  srv->ept.priv = srv;
+
+  ret = rpmsg_create_ept(&srv->ept, rdev, NOTERPMSG_EPT_NAME,
+                         RPMSG_ADDR_ANY, dest,
+                         noterpmsg_ept_cb, noterpmsg_ns_unbind);
+  if (ret < 0)
+    {
+      kmm_free(srv);
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: noterpmsg_server_init
+ *
+ * Description:
+ *   Register a rmpsg channel to note.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero on success. A negated errno value is returned on a failure.
+ *
+ ****************************************************************************/
+
+int noterpmsg_server_init(void)
+{
+  return rpmsg_register_callback(NULL,
+                                 NULL,
+                                 NULL,
+                                 noterpmsg_ns_match,
+                                 noterpmsg_ns_bind);
+}

Reply via email to