driver/sensor: add cmd SNIOC_UPDATED and remove readlast

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-06-28 15:50:37 +08:00 committed by Xiang Xiao
parent 12e5371a05
commit 5b91641a09
3 changed files with 30 additions and 64 deletions

View file

@ -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;

View file

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

View file

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