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 */
