mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 09:49:21 +08:00
driver/sensor: add cmd SNIOC_UPDATED and remove readlast
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
12e5371a05
commit
5b91641a09
3 changed files with 30 additions and 64 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue