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

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

commit 8127c485075dd4ddb88369b76eb8c9063ab64edc
Author: dongjiuzhu1 <[email protected]>
AuthorDate: Mon Jan 13 23:25:08 2025 +0800

    drivers/sensors: sensor rpmsg add new features.
    
    support set_nonwakeup ops for sensor driver to save power
    
    Signed-off-by: dongjiuzhu1 <[email protected]>
    Signed-off-by: likun17 <[email protected]>
---
 drivers/sensors/adxl362_uorb.c   |  1 +
 drivers/sensors/adxl372_uorb.c   |  1 +
 drivers/sensors/bh1749nuc_uorb.c |  1 +
 drivers/sensors/bme680_uorb.c    |  1 +
 drivers/sensors/bme688_uorb.c    |  1 +
 drivers/sensors/bmi270_uorb.c    |  1 +
 drivers/sensors/bmm150_uorb.c    |  1 +
 drivers/sensors/fs3000_uorb.c    |  1 +
 drivers/sensors/lsm9ds1_uorb.c   |  1 +
 drivers/sensors/ltr308_uorb.c    |  1 +
 drivers/sensors/mpu9250_uorb.c   |  1 +
 drivers/sensors/qmi8658_uorb.c   |  1 +
 drivers/sensors/sensor.c         | 58 +++++++++++++++++++++++++++++++++-------
 drivers/sensors/sensor_rpmsg.c   | 57 ++++++++++++++++++++++++++++++++++++---
 include/nuttx/sensors/ioctl.h    | 15 ++++++++---
 include/nuttx/sensors/sensor.h   | 19 +++++++++++++
 include/nuttx/uorb.h             |  5 +++-
 17 files changed, 148 insertions(+), 18 deletions(-)

diff --git a/drivers/sensors/adxl362_uorb.c b/drivers/sensors/adxl362_uorb.c
index dbb7ad628e4..11af01e5533 100644
--- a/drivers/sensors/adxl362_uorb.c
+++ b/drivers/sensors/adxl362_uorb.c
@@ -164,6 +164,7 @@ static const struct sensor_ops_s g_adxl362_accel_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   NULL,                 /* control */
 };
 
diff --git a/drivers/sensors/adxl372_uorb.c b/drivers/sensors/adxl372_uorb.c
index 460d4a9c642..3e22e702472 100644
--- a/drivers/sensors/adxl372_uorb.c
+++ b/drivers/sensors/adxl372_uorb.c
@@ -112,6 +112,7 @@ static const struct sensor_ops_s g_adxl372_accel_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL                  /* get_info */
+  NULL,                 /* set_nonwakeup */
   NULL                  /* control */
 };
 
diff --git a/drivers/sensors/bh1749nuc_uorb.c b/drivers/sensors/bh1749nuc_uorb.c
index 4ccaeaa186c..215a9982e45 100644
--- a/drivers/sensors/bh1749nuc_uorb.c
+++ b/drivers/sensors/bh1749nuc_uorb.c
@@ -113,6 +113,7 @@ static const struct sensor_ops_s g_bh1749nuc_sensor_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   bh1749nuc_control
 };
 
diff --git a/drivers/sensors/bme680_uorb.c b/drivers/sensors/bme680_uorb.c
index f23d2ea849e..512f517c634 100644
--- a/drivers/sensors/bme680_uorb.c
+++ b/drivers/sensors/bme680_uorb.c
@@ -430,6 +430,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,             /* set_calibvalue */
   bme680_calibrate, /* calibrate */
   NULL,             /* get_info */
+  NULL,             /* set_nonwakeup */
   bme680_control    /* control */
 };
 
diff --git a/drivers/sensors/bme688_uorb.c b/drivers/sensors/bme688_uorb.c
index 8b41137b678..741db1c44e4 100644
--- a/drivers/sensors/bme688_uorb.c
+++ b/drivers/sensors/bme688_uorb.c
@@ -383,6 +383,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,             /* set_calibvalue */
   bme688_calibrate, /* calibrate */
   NULL,             /* get_info */
+  NULL,             /* set_nonwakeup */
   bme688_control    /* control */
 };
 
diff --git a/drivers/sensors/bmi270_uorb.c b/drivers/sensors/bmi270_uorb.c
index 91405043710..fbc76c8d93c 100644
--- a/drivers/sensors/bmi270_uorb.c
+++ b/drivers/sensors/bmi270_uorb.c
@@ -133,6 +133,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   bmi270_control
 };
 
diff --git a/drivers/sensors/bmm150_uorb.c b/drivers/sensors/bmm150_uorb.c
index 09fda966f9d..ca55aa741a5 100644
--- a/drivers/sensors/bmm150_uorb.c
+++ b/drivers/sensors/bmm150_uorb.c
@@ -188,6 +188,7 @@ static const struct sensor_ops_s g_bmm150_sensor_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   NULL,                 /* control */
 };
 
diff --git a/drivers/sensors/fs3000_uorb.c b/drivers/sensors/fs3000_uorb.c
index 47135003799..f5f6e856d85 100644
--- a/drivers/sensors/fs3000_uorb.c
+++ b/drivers/sensors/fs3000_uorb.c
@@ -81,6 +81,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,               /* set_calibvalue */
   NULL,               /* calibrate */
   NULL,               /* get_info */
+  NULL,               /* set_nonwakeup */
   NULL                /* control */
 };
 
diff --git a/drivers/sensors/lsm9ds1_uorb.c b/drivers/sensors/lsm9ds1_uorb.c
index 70ac95191b8..a3e7d8281f3 100644
--- a/drivers/sensors/lsm9ds1_uorb.c
+++ b/drivers/sensors/lsm9ds1_uorb.c
@@ -136,6 +136,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   .control      = lsm9ds1_control
 };
 
diff --git a/drivers/sensors/ltr308_uorb.c b/drivers/sensors/ltr308_uorb.c
index 90d52d6a1fc..261efe2c67e 100644
--- a/drivers/sensors/ltr308_uorb.c
+++ b/drivers/sensors/ltr308_uorb.c
@@ -103,6 +103,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,               /* set_calibvalue */
   ltr308_calibrate,   /* calibrate */
   NULL,               /* get_info */
+  NULL,               /* set_nonwakeup */
   NULL                /* control */
 };
 
diff --git a/drivers/sensors/mpu9250_uorb.c b/drivers/sensors/mpu9250_uorb.c
index e5bbe22f018..da19d64a95d 100644
--- a/drivers/sensors/mpu9250_uorb.c
+++ b/drivers/sensors/mpu9250_uorb.c
@@ -381,6 +381,7 @@ static const struct sensor_ops_s g_mpu9250_ops =
   NULL,                 /* set_calibvalue */
   NULL,                 /* calibrate */
   NULL,                 /* get_info */
+  NULL,                 /* set_nonwakeup */
   mpu9250_control       /* control */
 };
 
diff --git a/drivers/sensors/qmi8658_uorb.c b/drivers/sensors/qmi8658_uorb.c
index 3d091f63f51..1cfddaaa586 100644
--- a/drivers/sensors/qmi8658_uorb.c
+++ b/drivers/sensors/qmi8658_uorb.c
@@ -358,6 +358,7 @@ static const struct sensor_ops_s g_sensor_ops =
   NULL,                   /* set_calibvalue */
   NULL,                   /* calibrate */
   NULL,                   /* get_info */
+  NULL,                   /* set_nonwakeup */
   NULL,                   /* control */
 };
 
diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index d23c83b54a6..46e33ca7bf9 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -440,6 +440,42 @@ update:
   return ret;
 }
 
+static void sensor_update_nonwakeup(FAR struct file *filep,
+                                    FAR struct sensor_upperhalf_s *upper,
+                                    FAR struct sensor_user_s *user,
+                                    bool nonwakeup)
+{
+  FAR struct sensor_lowerhalf_s *lower = upper->lower;
+
+  if (nonwakeup == user->state.nonwakeup)
+    {
+      return;
+    }
+
+  user->state.nonwakeup = nonwakeup;
+  nxrmutex_lock(&upper->lock);
+  list_for_every_entry(&upper->userlist, user, struct sensor_user_s,
+                       node)
+    {
+      if (!user->state.nonwakeup)
+        {
+          nonwakeup = false;
+          break;
+        }
+    }
+
+  if (nonwakeup != upper->state.nonwakeup)
+    {
+      upper->state.nonwakeup = nonwakeup;
+      if (lower->ops->set_nonwakeup)
+        {
+          lower->ops->set_nonwakeup(lower, filep, nonwakeup);
+        }
+    }
+
+  nxrmutex_unlock(&upper->lock);
+}
+
 static void sensor_generate_timing(FAR struct sensor_upperhalf_s *upper,
                                    unsigned long nums)
 {
@@ -716,6 +752,7 @@ static int sensor_open(FAR struct file *filep)
   user->state.esize = upper->state.esize;
   nxsem_init(&user->buffersem, 0, 0);
   list_add_tail(&upper->userlist, &user->node);
+  sensor_update_nonwakeup(filep, upper, user, false);
 
   /* The new user generation, notify to other users */
 
@@ -745,15 +782,15 @@ static int sensor_close(FAR struct file *filep)
   FAR struct sensor_user_s *user = filep->f_priv;
   int ret = 0;
 
+  sensor_update_interval(filep, upper, user, UINT32_MAX);
+  sensor_update_latency(filep, upper, user, UINT32_MAX);
+  sensor_update_nonwakeup(filep, upper, user, false);
+
   nxrmutex_lock(&upper->lock);
+
   if ((filep->f_oflags & O_DIRECT) == 0 && lower->ops->close)
     {
-      ret = lower->ops->close(lower, filep);
-      if (ret < 0)
-        {
-          nxrmutex_unlock(&upper->lock);
-          return ret;
-        }
+      lower->ops->close(lower, filep);
     }
 
   /* Using the O_DIRECT flag will prevent cross-core operations,
@@ -782,9 +819,6 @@ static int sensor_close(FAR struct file *filep)
   sensor_pollnotify(upper, POLLPRI, SENSOR_ROLE_WR);
   nxrmutex_unlock(&upper->lock);
 
-  sensor_update_latency(filep, upper, user, UINT32_MAX);
-  sensor_update_interval(filep, upper, user, UINT32_MAX);
-
   kmm_free(user);
   return ret;
 }
@@ -960,6 +994,12 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
         }
         break;
 
+      case SNIOC_SET_NONWAKEUP:
+        {
+          sensor_update_nonwakeup(filep, upper, user, (bool)arg);
+        }
+        break;
+
       case SNIOC_SET_BUFFER_NUMBER:
         {
           nxrmutex_lock(&upper->lock);
diff --git a/drivers/sensors/sensor_rpmsg.c b/drivers/sensors/sensor_rpmsg.c
index 63032e68a90..16e97f6a2ba 100644
--- a/drivers/sensors/sensor_rpmsg.c
+++ b/drivers/sensors/sensor_rpmsg.c
@@ -105,7 +105,6 @@ struct sensor_rpmsg_ept_s
 {
   struct list_node               node;
   struct rpmsg_endpoint          ept;
-  FAR struct rpmsg_device       *rdev;
   struct work_s                  work;
   rmutex_t                       lock;
   FAR void                      *buffer;
@@ -123,6 +122,7 @@ struct sensor_rpmsg_stub_s
   uint64_t                       cookie;
   struct file                    file;
   bool                           flushing;
+  bool                           nonwakeup;
 };
 
 /* This structure describes the proxy info about remote advertisers. */
@@ -227,6 +227,9 @@ static int sensor_rpmsg_calibrate(FAR struct 
sensor_lowerhalf_s *lower,
 static int sensor_rpmsg_get_info(FAR struct sensor_lowerhalf_s *lower,
                                  FAR struct file *filep,
                                  FAR struct sensor_device_info_s *info);
+static int sensor_rpmsg_set_nonwakeup(FAR struct sensor_lowerhalf_s *lower,
+                                      FAR struct file *filep,
+                                      bool nonwakeup);
 static int sensor_rpmsg_control(FAR struct sensor_lowerhalf_s *lower,
                                 FAR struct file *filep,
                                 int cmd, unsigned long arg);
@@ -274,6 +277,7 @@ static const struct sensor_ops_s g_sensor_rpmsg_ops =
   .set_calibvalue = sensor_rpmsg_set_calibvalue,
   .calibrate      = sensor_rpmsg_calibrate,
   .get_info       = sensor_rpmsg_get_info,
+  .set_nonwakeup  = sensor_rpmsg_set_nonwakeup,
   .control        = sensor_rpmsg_control
 };
 
@@ -793,7 +797,7 @@ static int sensor_rpmsg_flush(FAR struct sensor_lowerhalf_s 
*lower,
 
       return -ENOTSUP;
     }
-  else if (!(filep->f_oflags & SENSOR_REMOTE))
+  else
     {
       ret = sensor_rpmsg_ioctl(dev, SNIOC_FLUSH, 0, 0, true);
     }
@@ -801,6 +805,38 @@ static int sensor_rpmsg_flush(FAR struct 
sensor_lowerhalf_s *lower,
   return ret;
 }
 
+static int sensor_rpmsg_set_nonwakeup(FAR struct sensor_lowerhalf_s *lower,
+                                      FAR struct file *filep,
+                                      bool nonwakeup)
+{
+  FAR struct sensor_rpmsg_dev_s *dev = lower->priv;
+  FAR struct sensor_lowerhalf_s *drv = dev->drv;
+  int ret = -ENOTTY;
+
+  if (drv->ops->set_nonwakeup)
+    {
+      ret = drv->ops->set_nonwakeup(drv, filep, nonwakeup);
+    }
+  else if ((filep->f_oflags & SENSOR_REMOTE) ||
+           dev->nadvertisers > 0)
+    {
+      /* If the driver (drv) does not support the nonwakeup operation,
+       * and the caller is a remote invocation or the current device
+       * is an advertiser, then you can still consider the nonwakeup
+       * operation as unsupported and therefore return ENOTSUP
+       */
+
+      return -ENOTSUP;
+    }
+  else
+    {
+      ret = sensor_rpmsg_ioctl(dev, SNIOC_SET_NONWAKEUP,
+                               nonwakeup, 0, true);
+    }
+
+  return ret;
+}
+
 static int sensor_rpmsg_get_info(FAR struct sensor_lowerhalf_s *lower,
                                  FAR struct file *filep,
                                  FAR struct sensor_device_info_s *info)
@@ -879,6 +915,16 @@ static void sensor_rpmsg_push_event_one(FAR struct 
sensor_rpmsg_dev_s *dev,
   bool updated;
   int ret;
 
+  /* If stub is non wakeup and remote cpu is sleep, don't send data
+   * to remote
+   */
+
+  sre = container_of(stub->ept, struct sensor_rpmsg_ept_s, ept);
+  if (stub->nonwakeup && !rpmsg_is_running(sre->ept.rdev))
+    {
+      return;
+    }
+
   /* Get state of device to do send data with timeout */
 
   ret = file_ioctl(&stub->file, SNIOC_GET_USTATE, &state);
@@ -892,7 +938,6 @@ static void sensor_rpmsg_push_event_one(FAR struct 
sensor_rpmsg_dev_s *dev,
       state.interval = 0;
     }
 
-  sre = container_of(stub->ept, struct sensor_rpmsg_ept_s, ept);
   nxrmutex_lock(&sre->lock);
 
   /* Cancel work to fill new data to buffer */
@@ -1301,6 +1346,11 @@ static int sensor_rpmsg_ioctl_handler(FAR struct 
rpmsg_endpoint *ept,
               stub->flushing = true;
             }
 
+          if (msg->request == SNIOC_SET_NONWAKEUP)
+            {
+              stub->nonwakeup = arg;
+            }
+
           if (msg->cookie)
             {
               msg->command = SENSOR_RPMSG_IOCTL_ACK;
@@ -1454,7 +1504,6 @@ static void sensor_rpmsg_device_created(FAR struct 
rpmsg_device *rdev,
       return;
     }
 
-  sre->rdev = rdev;
   sre->ept.priv = sre;
   nxrmutex_init(&sre->lock);
   sre->ept.ns_bound_cb = sensor_rpmsg_device_ns_bound;
diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h
index 9bb198c2902..5cc397f76de 100644
--- a/include/nuttx/sensors/ioctl.h
+++ b/include/nuttx/sensors/ioctl.h
@@ -435,27 +435,27 @@
  * Argument:     Heater configuration.
  */
 
-#define SNIOC_HEAT             _SNIOC(0x009B)
+#define SNIOC_HEAT                    _SNIOC(0x009B)
 
 /* Command:      SNIOC_GET_INFO
  * Description:  Get device information.
  * Argument:     This is the device info pointer.
  */
 
-#define SNIOC_GET_INFO                _SNIOC(0x009B)
+#define SNIOC_GET_INFO                _SNIOC(0x009C)
 
 /* Command:      SNIOC_FLUSH
  * Description:  Flush sensor hardware fifo buffer.
  */
 
-#define SNIOC_FLUSH                   _SNIOC(0x009C)
+#define SNIOC_FLUSH                   _SNIOC(0x009D)
 
 /* Command:      SNIOC_GET_EVENTS
  * Description:  Get events of the sensor device.
  * Argument:     The events pointer, (unsigned int *)
  */
 
-#define SNIOC_GET_EVENTS              _SNIOC(0x009D)
+#define SNIOC_GET_EVENTS              _SNIOC(0x009E)
 
 /* Command:      SNIOC_SET_THERMO
  * Description:  Set the thermocouple type.
@@ -502,6 +502,13 @@
 #define SNIOC_COLD_START              _SNIOC(0X00A7)
 #define SNIOC_FULL_COLD_START         _SNIOC(0X00A8)
 
+/* Command:      SNIOC_SET_NONWAKEUP
+ * Description:  Set non-wakeup flag for user.
+ * Argument:     True is non-wakeup, false is wakeup.
+ */
+
+#define SNIOC_SET_NONWAKEUP           _SNIOC(0x00A9)
+
 /****************************************************************************
  * Public types
  ****************************************************************************/
diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h
index 899ecdf811e..c4e275bd15a 100644
--- a/include/nuttx/sensors/sensor.h
+++ b/include/nuttx/sensors/sensor.h
@@ -478,6 +478,25 @@ struct sensor_ops_s
                        FAR struct file *filep,
                        FAR struct sensor_device_info_s *info);
 
+  /**************************************************************************
+   * Name: set_nonwakeup
+   *
+   * With this method, the user can disable wakeup capacity for the sensor
+   * when data or fifo ready to avoid wakeup cpu, and save power.
+   *
+   * Input Parameters:
+   *   lower      - The instance of lower half sensor driver.
+   *   filep      - The pointer of file, represents each user using sensor.
+   *   nonwakeup  - true(nonwakeup) and false(wakeup)
+   *
+   * Returned Value:
+   *   Zero (OK) on success; a negated errno value on failure.
+   *
+   **************************************************************************/
+
+  CODE int (*set_nonwakeup)(FAR struct sensor_lowerhalf_s *lower,
+                            FAR struct file *filep, bool nonwakeup);
+
   /**************************************************************************
    * Name: control
    *
diff --git a/include/nuttx/uorb.h b/include/nuttx/uorb.h
index cd768145e64..0b04e08b324 100644
--- a/include/nuttx/uorb.h
+++ b/include/nuttx/uorb.h
@@ -475,6 +475,7 @@
 /* GNSS Geofence */
 
 #define SENSOR_TYPE_GNSS_GEOFENCE                   52
+
 /* Velocity Sensor
  * A sensor of this type measures the velocity as it is moving.
  * The default unit velocity is meter by seconds m/s (SI).
@@ -1207,6 +1208,7 @@ struct sensor_state_s
   uint32_t nsubscribers;       /* The number of subscribers */
   uint32_t nadvertisers;       /* The number of advertisers */
   uint32_t generation;         /* The recent generation of circular buffer */
+  uint32_t nonwakeup;          /* The non wakeup state of sensor device */
   uint64_t priv;               /* The pointer to private data of userspace 
user */
 };
 
@@ -1217,7 +1219,8 @@ struct sensor_ustate_s
   uint32_t esize;              /* The element size of circular buffer */
   uint32_t latency;            /* The batch latency for user, in us */
   uint32_t interval;           /* The subscription interval for user, in us */
-  uint64_t generation;         /* The recent generation of circular buffer */
+  uint32_t nonwakeup;          /* The non wakeup state of sensor user */
+  uint32_t generation;         /* The recent generation of circular buffer */
 };
 
 /* This structure describes the context custom ioctl for device */

Reply via email to