You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2022/07/23 19:58:11 UTC

[incubator-nuttx-apps] 08/20: uorb/listener: add new api: orb_open and orb_close

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

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

commit 53ee04ba3c22de569bbddf15205975149158b07b
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Thu Apr 28 23:17:57 2022 +0800

    uorb/listener: add new api: orb_open and orb_close
    
    don't using subscriber to get state to avoid rpmsg access
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 system/uorb/listener.c  |  34 +++++---------
 system/uorb/uORB/uORB.c |  66 +++++++++++++-------------
 system/uorb/uORB/uORB.h | 120 +++++++++++++++++++++++++++++++-----------------
 3 files changed, 124 insertions(+), 96 deletions(-)

diff --git a/system/uorb/listener.c b/system/uorb/listener.c
index 5b18a54cf..579b2c8b7 100644
--- a/system/uorb/listener.c
+++ b/system/uorb/listener.c
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include <uORB/uORB.h>
 
@@ -139,21 +140,15 @@ static int listener_get_state(FAR struct orb_object *object,
   int ret;
   int fd;
 
-  fd = orb_subscribe_multi(object->meta, object->instance);
+  fd = orb_open(object->meta->o_name, object->instance, 0);
   if (fd < 0)
     {
       return fd;
     }
 
   ret = orb_get_state(fd, state);
-  orb_unsubscribe(fd);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  state->nsubscribers--; /* Ignore temp subscriber */
-  return 0;
+  orb_close(fd);
+  return ret;
 }
 
 /****************************************************************************
@@ -174,8 +169,6 @@ static int listener_add_object(FAR struct list_node *objlist,
                                FAR struct orb_object *object)
 {
   FAR struct listen_object_s *tmp;
-  struct orb_state state;
-  int ret;
 
   tmp = malloc(sizeof(struct listen_object_s));
   if (tmp == NULL)
@@ -183,20 +176,10 @@ static int listener_add_object(FAR struct list_node *objlist,
       return -ENOMEM;
     }
 
-  ret = listener_get_state(object, &state);
-  if (ret < 0)
-    {
-      free(tmp);
-      return ret;
-    }
-
   tmp->object.meta     = object->meta;
   tmp->object.instance = object->instance;
-  tmp->timestamp       = orb_absolute_time();
-  tmp->generation      = state.generation;
-
+  tmp->timestamp       = 0;
   list_add_tail(objlist, &tmp->node);
-
   return 0;
 }
 
@@ -249,6 +232,13 @@ static int listener_update(FAR struct list_node *objlist,
           return ret;
         }
 
+      if (old->timestamp == 0)
+        {
+          old->timestamp  = orb_absolute_time();
+          old->generation = state.generation;
+          return 0;
+        }
+
       delta_time       = now_time - old->timestamp;
       delta_generation = state.generation - old->generation;
       if (delta_generation && delta_time)
diff --git a/system/uorb/uORB/uORB.c b/system/uorb/uORB/uORB.c
index 5fdf16e9f..2d02378a4 100644
--- a/system/uorb/uORB/uORB.c
+++ b/system/uorb/uORB/uORB.c
@@ -37,7 +37,7 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: orb_open
+ * Name: orb_advsub_open
  *
  * Description:
  *   Open device node as advertiser / subscriber, regist node and save meta
@@ -45,7 +45,7 @@
  *
  * Input Parameters:
  *   meta         The uORB metadata (usually from the ORB_ID() macro)
- *   advertiser   Whether advertiser or subscriber.
+ *   flag         The open flag.
  *   instance     Instance number to open.
  *   queue_size   Maximum number of buffered elements.
  *
@@ -53,11 +53,10 @@
  *   fd on success, otherwise returns negative value and set errno.
  ****************************************************************************/
 
-static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
-                    int instance, unsigned int queue_size)
+static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags,
+                           int instance, unsigned int queue_size)
 {
   char path[ORB_PATH_MAX];
-  bool first_open = false;
   int fd;
   int ret;
 
@@ -66,11 +65,11 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
 
   /* Check existance before open */
 
-  ret = access(path, F_OK);
-  if (ret < 0)
+  flags |= O_CLOEXEC;
+  fd = open(path, flags);
+  if (fd < 0)
     {
       struct sensor_reginfo_s reginfo;
-
       reginfo.path    = path;
       reginfo.esize   = meta->o_size;
       reginfo.nbuffer = queue_size;
@@ -90,18 +89,16 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
           return ret;
         }
 
-      first_open = true;
-    }
-
-  fd = open(path, O_CLOEXEC | (advertiser ? O_WRONLY : O_RDONLY));
-  if (fd < 0)
-    {
-      return fd;
-    }
+      fd = open(path, flags);
+      if (fd < 0)
+        {
+          return fd;
+        }
 
-  if (first_open)
-    {
-      ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
+      if (ret != -EEXIST)
+        {
+          ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
+        }
     }
 
   /* Only first advertiser can successfully set buffer number */
@@ -118,6 +115,19 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
  * Public Functions
  ****************************************************************************/
 
+int orb_open(FAR const char *name, int instance, int flags)
+{
+  char path[ORB_PATH_MAX];
+
+  snprintf(path, ORB_PATH_MAX, ORB_SENSOR_PATH"%s%d", name, instance);
+  return open(path, O_CLOEXEC | flags);
+}
+
+int orb_close(int fd)
+{
+  return close(fd);
+}
+
 int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
                               FAR const void *data, FAR int *instance,
                               unsigned int queue_size)
@@ -129,7 +139,7 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
 
   inst = instance ? *instance : orb_group_count(meta);
 
-  fd = orb_open(meta, true, inst, queue_size);
+  fd = orb_advsub_open(meta, O_WRONLY, inst, queue_size);
   if (fd < 0)
     {
       uorberr("%s advertise failed (%i)", meta->o_name, fd);
@@ -155,11 +165,6 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
   return fd;
 }
 
-int orb_unadvertise(int fd)
-{
-  return close(fd);
-}
-
 ssize_t orb_publish_multi(int fd, const void *data, size_t len)
 {
   return write(fd, data, len);
@@ -168,12 +173,7 @@ ssize_t orb_publish_multi(int fd, const void *data, size_t len)
 int orb_subscribe_multi(FAR const struct orb_metadata *meta,
                         unsigned instance)
 {
-  return orb_open(meta, false, instance, 0);
-}
-
-int orb_unsubscribe(int fd)
-{
-  return close(fd);
+  return orb_advsub_open(meta, O_RDONLY, instance, 0);
 }
 
 ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len)
@@ -225,9 +225,9 @@ int orb_check(int fd, FAR bool *updated)
   return 0;
 }
 
-int orb_ioctl(int handle, int cmd, unsigned long arg)
+int orb_ioctl(int fd, int cmd, unsigned long arg)
 {
-  return ioctl(handle, cmd, arg);
+  return ioctl(fd, cmd, arg);
 }
 
 int orb_set_interval(int fd, unsigned interval)
diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h
index 5161c31f6..b59913d75 100644
--- a/system/uorb/uORB/uORB.h
+++ b/system/uorb/uORB/uORB.h
@@ -173,6 +173,38 @@ extern "C"
  * Public Function Prototypes
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: orb_open
+ *
+ * Description:
+ *   Open device exist node with name, instance and flags.
+ *
+ * Input Parameters:
+ *   name         The topic name.
+ *   instance     Instance number to open.
+ *   flags        The open flags.
+ *
+ * Returned Value:
+ *   fd on success, otherwise returns negative value and set errno.
+ ****************************************************************************/
+
+int orb_open(FAR const char *name, int instance, int flags);
+
+/****************************************************************************
+ * Name: orb_close
+ *
+ * Description:
+ *   Close fd.
+ *
+ * Input Parameters:
+ *   fd       A fd returned by orb_open.
+ *
+ * Returned Value:
+ *   0 on success.
+ ****************************************************************************/
+
+int orb_close(int fd);
+
 /****************************************************************************
  * Name: orb_advertise_multi_queue
  *
@@ -227,13 +259,16 @@ static inline int orb_advertise_multi(FAR const struct orb_metadata *meta,
  *   Unadvertise a topic.
  *
  * Input Parameters:
- *   handle   A handle returned by orb_advertise or orb_advertise_multi.
+ *   fd       A fd returned by orb_advertise or orb_advertise_multi.
  *
  * Returned Value:
  *   0 on success.
  ****************************************************************************/
 
-int orb_unadvertise(int handle);
+static inline int orb_unadvertise(int fd)
+{
+  return orb_close(fd);
+}
 
 /****************************************************************************
  * Name: orb_publish_multi
@@ -246,7 +281,7 @@ int orb_unadvertise(int handle);
  *   updates using orb_check.
  *
  * Input Parameters:
- *   handle   The handle returned from orb_advertise.
+ *   fd       The fd returned from orb_advertise.
  *   data     A pointer to the data to be published.
  *   len      The length of the data to be published.
  *
@@ -254,24 +289,24 @@ int orb_unadvertise(int handle);
  *   0 on success, -1 otherwise with errno set accordingly.
  ****************************************************************************/
 
-ssize_t orb_publish_multi(int handle, FAR const void *data, size_t len);
+ssize_t orb_publish_multi(int fd, FAR const void *data, size_t len);
 
 static inline int orb_publish(FAR const struct orb_metadata *meta,
-                              int handle, FAR const void *data)
+                              int fd, FAR const void *data)
 {
   int ret;
 
-  ret = orb_publish_multi(handle, data, meta->o_size);
+  ret = orb_publish_multi(fd, data, meta->o_size);
   return ret == meta->o_size ? 0 : -1;
 }
 
 static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
-                                   FAR int *handle, FAR const void *data,
+                                   FAR int *fd, FAR const void *data,
                                    FAR int *instance)
 {
-  if (handle && *handle)
+  if (fd && *fd)
     {
-      return orb_publish(meta, *handle, data);
+      return orb_publish(meta, *fd, data);
     }
   else
     {
@@ -283,9 +318,9 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
           return tmp;
         }
 
-      if (handle)
+      if (fd)
         {
-          *handle = tmp;
+          *fd = tmp;
           return tmp;
         }
       else
@@ -319,7 +354,7 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
  *              the orb_subscribe() call.
  *
  * Returned Value:
- *   -1 on error, otherwise returns a handle
+ *   -1 on error, otherwise returns a fd
  *   that can be used to read and update the topic.
  *   If the topic in question is not known (due to an
  *   ORB_DEFINE_OPTIONAL with no corresponding ORB_DECLARE)
@@ -341,13 +376,16 @@ static inline int orb_subscribe(FAR const struct orb_metadata *meta)
  *   Unsubscribe from a topic.
  *
  * Input Parameters:
- *   handle   A handle returned from orb_subscribe.
+ *   fd       A fd returned from orb_subscribe.
  *
  * Returned Value:
  *   0 on success.
  ****************************************************************************/
 
-int orb_unsubscribe(int handle);
+static inline int orb_unsubscribe(int fd)
+{
+  return orb_close(fd);
+}
 
 /****************************************************************************
  * Name: orb_copy_multi
@@ -361,7 +399,7 @@ int orb_unsubscribe(int handle);
  *   must be used to update the subscription.
  *
  * Input Parameters:
- *   handle   A handle returned from orb_subscribe.
+ *   fd       A fd returned from orb_subscribe.
  *   buffer   Pointer to the buffer receiving the data, or NULL if the
  *            caller wants to clear the updated flag without.
  *   len      The length to the buffer receiving the data.
@@ -372,14 +410,14 @@ int orb_unsubscribe(int handle);
  *   -1 otherwise with errno set accordingly.
  ****************************************************************************/
 
-ssize_t orb_copy_multi(int handle, FAR void *buffer, size_t len);
+ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len);
 
 static inline int orb_copy(FAR const struct orb_metadata *meta,
-                           int handle, FAR void *buffer)
+                           int fd, FAR void *buffer)
 {
   int ret;
 
-  ret = orb_copy_multi(handle, buffer, meta->o_size);
+  ret = orb_copy_multi(fd, buffer, meta->o_size);
   return ret == meta->o_size ? 0 : -1;
 }
 
@@ -397,7 +435,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
  *     max_frequency to 0. min_batch_interval to 0, enable to false.
  *
  * Input Parameters:
- *   handle   The handle returned from orb_advertise / orb_subscribe.
+ *   fd       The fd returned from orb_advertise / orb_subscribe.
  *   state    Pointer to an state of struct orb_state type. This is an
  *            output parameter and will be set to the current state of topic.
  *
@@ -405,7 +443,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
  *   -1 on error.
  ****************************************************************************/
 
-int orb_get_state(int handle, FAR struct orb_state *state);
+int orb_get_state(int fd, FAR struct orb_state *state);
 
 /****************************************************************************
  * Name: orb_check
@@ -417,20 +455,20 @@ int orb_get_state(int handle, FAR struct orb_state *state);
  *   not using poll(), or to avoid the overhead of calling poll() when the
  *   topic is likely to have updated.
  *
- *   Updates are tracked on a per-handle basis; this call will continue to
- *   return true until orb_copy is called using the same handle.
+ *   Updates are tracked on a per-fd basis; this call will continue to
+ *   return true until orb_copy is called using the same fd.
  *
  * Input Parameters:
- *   handle   A handle returned from orb_subscribe.
+ *   fd       A fd returned from orb_subscribe.
  *   update   Set to true if the topic has been updated since the
- *            last time it was copied using this handle.
+ *            last time it was copied using this fd.
  *
  * Returned Value:
  *   0 if the check was successful,
  *   -1 otherwise with errno set accordingly.
  ****************************************************************************/
 
-int orb_check(int handle, FAR bool *updated);
+int orb_check(int fd, FAR bool *updated);
 
 /****************************************************************************
  * Name: orb_ioctl
@@ -439,7 +477,7 @@ int orb_check(int handle, FAR bool *updated);
  *   Ioctl control for the subscriber, the same as ioctl().
  *
  * Input Parameters:
- *   handle   A handle returned from orb_advertise / orb_subscribe.
+ *   fd       A fd returned from orb_advertise / orb_subscribe.
  *   cmd      Ioctl command.
  *   arg      Ioctl argument.
  *
@@ -447,7 +485,7 @@ int orb_check(int handle, FAR bool *updated);
  *   0 on success.
  ****************************************************************************/
 
-int orb_ioctl(int handle, int cmd, unsigned long arg);
+int orb_ioctl(int fd, int cmd, unsigned long arg);
 
 /****************************************************************************
  * Name: orb_set_batch_interval
@@ -462,14 +500,14 @@ int orb_ioctl(int handle, int cmd, unsigned long arg);
  *   hardware fifo, otherwise it's meaningless.
  *
  * Input Parameters:
- *   handle         A handle returned from orb_subscribe.
+ *   fd             A fd returned from orb_subscribe.
  *   batch_interval An batch interval in us.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-int orb_set_batch_interval(int handle, unsigned batch_interval);
+int orb_set_batch_interval(int fd, unsigned batch_interval);
 
 /****************************************************************************
  * Name: orb_get_batch_interval
@@ -483,14 +521,14 @@ int orb_set_batch_interval(int handle, unsigned batch_interval);
  *   @see orb_set_batch_interval()
  *
  * Input Parameters:
- *   handle          A handle returned from orb_subscribe.
+ *   fd              A fd returned from orb_subscribe.
  *   batch_interval  The returned batch interval in us.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-int orb_get_batch_interval(int handle, FAR unsigned *batch_interval);
+int orb_get_batch_interval(int fd, FAR unsigned *batch_interval);
 
 /****************************************************************************
  * Name:
@@ -499,14 +537,14 @@ int orb_get_batch_interval(int handle, FAR unsigned *batch_interval);
  *   Set the minimum interval between which updates seen for a subscription.
  *
  * Input Parameters:
- *   handle     A handle returned from orb_subscribe.
+ *   fd         A fd returned from orb_subscribe.
  *   interval   An interval period in us.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-int orb_set_interval(int handle, unsigned interval);
+int orb_set_interval(int fd, unsigned interval);
 
 /****************************************************************************
  * Name:
@@ -515,14 +553,14 @@ int orb_set_interval(int handle, unsigned interval);
  *   Get the minimum interval between which updates seen for a subscription.
  *
  * Input Parameters:
- *   handle     A handle returned from orb_subscribe.
+ *   fd         A fd returned from orb_subscribe.
  *   interval   The returned interval period in us.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-int orb_get_interval(int handle, FAR unsigned *interval);
+int orb_get_interval(int fd, FAR unsigned *interval);
 
 /****************************************************************************
  * Name:
@@ -532,16 +570,16 @@ int orb_get_interval(int handle, FAR unsigned *interval);
  *   Set the maximum frequency for a subscription.
  *
  * Input Parameters:
- *   handle     A handle returned from orb_subscribe.
+ *   fd         A fd returned from orb_subscribe.
  *   frequency  A frequency in hz.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-static inline int orb_set_frequency(int handle, unsigned frequency)
+static inline int orb_set_frequency(int fd, unsigned frequency)
 {
-  return orb_set_interval(handle, frequency ? 1000000 / frequency : 0);
+  return orb_set_interval(fd, frequency ? 1000000 / frequency : 0);
 }
 
 /****************************************************************************
@@ -552,19 +590,19 @@ static inline int orb_set_frequency(int handle, unsigned frequency)
  *   Get the maximum frequency for a subscription.
  *
  * Input Parameters:
- *   handle     A handle returned from orb_subscribe.
+ *   fd         A fd returned from orb_subscribe.
  *   frequency  The returned frequency in hz.
  *
  * Returned Value:
  *   0 on success, -1 otherwise with ERRNO set accordingly.
  ****************************************************************************/
 
-static inline int orb_get_frequency(int handle, FAR unsigned *frequency)
+static inline int orb_get_frequency(int fd, FAR unsigned *frequency)
 {
   unsigned interval;
   int ret;
 
-  ret = orb_get_interval(handle, &interval);
+  ret = orb_get_interval(fd, &interval);
   if (ret < 0)
     {
       return ret;