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/08/01 17:29:23 UTC

[incubator-nuttx] 19/22: driver/sensor: add cmd SNIOC_UPDATED and remove readlast

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

commit 5b91641a09374e7bf798b11c8903067bf0fb0f37
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Tue Jun 28 15:50:37 2022 +0800

    driver/sensor: add cmd SNIOC_UPDATED and remove readlast
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 drivers/sensors/sensor.c       | 75 ++++++++++--------------------------------
 drivers/sensors/sensor_rpmsg.c |  8 ++++-
 include/nuttx/sensors/ioctl.h  | 11 +++----
 3 files changed, 30 insertions(+), 64 deletions(-)

diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index 99544231bf..50e9d33cc8 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -85,7 +85,6 @@ struct sensor_user_s
   unsigned long    generation; /* Last generation subscriber has seen */
   unsigned long    interval;   /* The interval for subscriber */
   unsigned long    latency;    /* The bactch latency for subscriber */
-  bool             readlast;   /* The flag of readlast */
 };
 
 /* This structure describes the state of the upper half driver */
@@ -447,7 +446,6 @@ static int sensor_open(FAR struct file *filep)
     }
 
   user->interval = ULONG_MAX;
-  user->readlast = true;
   nxsem_init(&user->buffersem, 0, 0);
   nxsem_set_protocol(&user->buffersem, SEM_PRIO_NONE);
   list_add_tail(&upper->userlist, &user->node);
@@ -558,65 +556,27 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
     }
   else
     {
-      /* If readlast is true, you can always read the last data
-       * in the circbuffer as initial value for new users when the
-       * sensor device has not yet generated new data, otherwise,
-       * it will return 0 when there isn't new data.
+      if (circbuf_is_empty(&upper->buffer))
+        {
+          ret = -ENODATA;
+          goto out;
+        }
+
+      /* If the device data is persistent, and when the device has
+       * no new data, the user can copy the old data, otherwise
+       * return -ENODATA.
        */
 
-      if (user->readlast)
+      if (user->generation == upper->state.generation)
         {
-          if (circbuf_is_empty(&upper->buffer))
+          if (lower->persist)
             {
-              ret = -ENODATA;
-              goto out;
+              user->generation--;
             }
-
-          /* If the device data is persistent, and when the device has no
-           * new data, the user can copy the old data, otherwise return
-           * -ENODATA.
-           */
-
-          if (user->generation == upper->state.generation)
-            {
-              if (lower->persist)
-                {
-                  user->generation--;
-                }
-              else
-                {
-                  ret = -ENODATA;
-                  goto out;
-                }
-            }
-        }
-      else
-        {
-          /* We must make sure that when the semaphore is equal to 1,
-           * there must be events available in the buffer, so we use a
-           * while statement to synchronize this case that other read
-           * operations consume events that have just entered the buffer.
-           */
-
-          while (circbuf_is_empty(&upper->buffer) ||
-                 user->generation == upper->state.generation)
+          else
             {
-              if (filep->f_oflags & O_NONBLOCK)
-                {
-                  ret = -EAGAIN;
-                  goto out;
-                }
-              else
-                {
-                  nxrmutex_unlock(&upper->lock);
-                  ret = nxsem_wait_uninterruptible(&user->buffersem);
-                  if (ret < 0)
-                    {
-                      return ret;
-                    }
-
-                  nxrmutex_lock(&upper->lock);
-                }
+              ret = -ENODATA;
+              goto out;
             }
         }
 
@@ -765,10 +725,11 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         }
         break;
 
-      case SNIOC_READLAST:
+      case SNIOC_UPDATED:
         {
           nxrmutex_lock(&upper->lock);
-          user->readlast = !!arg;
+          *(FAR bool *)(uintptr_t)arg =
+          sensor_is_updated(upper->state.generation, user->generation);
           nxrmutex_unlock(&upper->lock);
         }
         break;
diff --git a/drivers/sensors/sensor_rpmsg.c b/drivers/sensors/sensor_rpmsg.c
index 8aa9f263d2..2b608d3f3e 100644
--- a/drivers/sensors/sensor_rpmsg.c
+++ b/drivers/sensors/sensor_rpmsg.c
@@ -539,7 +539,6 @@ sensor_rpmsg_alloc_stub(FAR struct sensor_rpmsg_dev_s *dev,
       return NULL;
     }
 
-  file_ioctl(&stub->file, SNIOC_READLAST, false);
   sensor_rpmsg_lock(dev);
   list_add_tail(&dev->stublist, &stub->node);
   sensor_rpmsg_unlock(dev);
@@ -729,6 +728,7 @@ static void sensor_rpmsg_push_event_one(FAR struct sensor_rpmsg_dev_s *dev,
   FAR struct sensor_rpmsg_data_s *msg;
   struct sensor_state_s state;
   uint64_t now;
+  bool updated;
   int ret;
 
   /* Get state of device to do send data with timeout */
@@ -756,6 +756,12 @@ static void sensor_rpmsg_push_event_one(FAR struct sensor_rpmsg_dev_s *dev,
 
   for (; ; )
     {
+      ret = file_ioctl(&stub->file, SNIOC_UPDATED, &updated);
+      if (ret < 0 || !updated)
+        {
+          break;
+        }
+
       /* If buffer isn't created or it doesn't have enough space to fill
        * new data, you should create or send this buffer at once.
        */
diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h
index 1e415a98cc..992367cc14 100644
--- a/include/nuttx/sensors/ioctl.h
+++ b/include/nuttx/sensors/ioctl.h
@@ -326,13 +326,12 @@
 #define SNIOC_UNREGISTER           _SNIOC(0x0090)
 #endif
 
-/* Command:      SNIOC_READLAST
- * Description:  If enable readlast, there is no data update in time,
- *               the latest data can always be returned.
- *               Disable readlast, if there is no data update, return 0.
- * Argument:     True or false
+/* Command:      SNIOC_UPDATED
+ * Description:  Check whether the topic has been updated since
+ *               it was last read.
+ * Argument:     Sets *(bool *)arg
  */
 
-#define SNIOC_READLAST             _SNIOC(0x0091)
+#define SNIOC_UPDATED              _SNIOC(0x0091)
 
 #endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */