diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index 99544231bf0..50e9d33cc8f 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,66 +556,28 @@ 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) + { + user->generation--; + } + else { 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->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) - { - 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); - } - } } /* If user's generation isn't within circbuffer range, the @@ -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 8aa9f263d2d..2b608d3f3e0 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 1e415a98cc3..992367cc140 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 */