You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2026/08/05 10:50:20 UTC
(nuttx) 02/03: drivers/sensors/sensor: always report POLLIN for fetch only sensor
This is an automated email from the ASF dual-hosted git repository.
jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4d3c5cac467232b985f48c29fab664f4f4543325
Author: Felipe Moura <mo...@gmail.com>
AuthorDate: Sat Aug 1 12:37:00 2026 -0300
drivers/sensors/sensor: always report POLLIN for fetch only sensor
A fetch() only lower half reads the device on demand, so its data is
always available and there is never anything to wait for. The upper half
did not reflect that: poll() only reported POLLIN when the descriptor was
opened O_NONBLOCK, and a blocking read() waited on buffersem, which is
only posted when the lower half drives notify_event from an interrupt of
its own.
A fetch() only sensor with no interrupt therefore never satisfied
poll()/read() at all. This is not hypothetical: in the in tree
nucleo-h563zi:dts configuration CONFIG_STM32_DTS_TRIGGER defaults to 0,
which selects stm32_dts_fetch(), and no CONFIG_STM32_DTS_ITEN_* option is
enabled, so the DTS interrupt never fires. A blocking read() on that
sensor waits forever, even though stm32_dts_fetch() performs a complete
software triggered measurement on its own and needs no interrupt at all.
Applications had to work around this by forcing O_NONBLOCK on the
descriptor themselves, see apache/nuttx-apps#3686.
Drop the O_NONBLOCK special case in both paths: sensor_poll() now always
reports POLLIN for a fetch only sensor and sensor_read() calls fetch()
directly instead of waiting. Update the sensor_ops_s::fetch
documentation, which described the old contract.
With the wait gone, buffersem has no waiters left. Its only two readers
were the ones removed here, both in the fetch path: the wait in
sensor_read() and the nxsem_get_value() in sensor_poll(). The remaining
nxsem_post() calls in sensor_push_event() and sensor_notify_event() had
nothing left to wake, so drop the semaphore and those posts as well.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Felipe Moura <mo...@gmail.com>
---
drivers/sensors/sensor.c | 54 +++++++++---------------------------------
include/nuttx/sensors/sensor.h | 8 +++----
2 files changed, 15 insertions(+), 47 deletions(-)
diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index cb88cb33e17..ef08737ae82 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -101,7 +101,6 @@ struct sensor_user_s
*/
unsigned int event; /* The event of this sensor, eg: SENSOR_EVENT_FLUSH_COMPLETE. */
bool flushing; /* The is used to indicate user is flushing */
- sem_t buffersem; /* Wakeup user waiting for data in circular buffer */
size_t bufferpos; /* The index of user generation in buffer */
/* The subscriber info
@@ -774,7 +773,6 @@ static int sensor_open(FAR struct file *filep)
user->state.interval = UINT32_MAX;
user->state.esize = upper->state.esize;
user->state.nonwakeup = true;
- nxsem_init(&user->buffersem, 0, 0);
list_add_tail(&upper->userlist, &user->node);
/* The new user generation, notify to other users */
@@ -835,7 +833,6 @@ static int sensor_close(FAR struct file *filep)
}
list_delete(&user->node);
- nxsem_destroy(&user->buffersem);
/* The user is closed, notify to other users */
@@ -871,24 +868,18 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
return -EINVAL;
}
- if (!(filep->f_oflags & O_NONBLOCK))
- {
- nxrmutex_unlock(&upper->lock);
- ret = nxsem_wait_uninterruptible(&user->buffersem);
- if (ret < 0)
- {
- return ret;
- }
+ /* Fetch the data from the device directly, there is nothing to wait
+ * for. This matches the POLLIN sensor_poll() always reports for a
+ * fetch only sensor.
+ */
- nxrmutex_lock(&upper->lock);
- }
- else if (!upper->state.nsubscribers)
+ if (!upper->state.nsubscribers)
{
ret = -EAGAIN;
goto out;
}
- ret = lower->ops->fetch(lower, filep, buffer, len);
+ ret = lower->ops->fetch(lower, filep, buffer, len);
}
else if (circbuf_is_empty(&upper->buffer))
{
@@ -1166,7 +1157,6 @@ static int sensor_poll(FAR struct file *filep,
FAR struct sensor_lowerhalf_s *lower = upper->lower;
FAR struct sensor_user_s *user = filep->f_priv;
pollevent_t eventset = 0;
- int semcount;
int ret = 0;
nxrmutex_lock(&upper->lock);
@@ -1184,20 +1174,12 @@ static int sensor_poll(FAR struct file *filep,
fds->priv = filep;
if (lower->ops->fetch)
{
- /* Always return POLLIN for fetch data directly(non-block) */
+ /* Always return POLLIN for fetch only sensor: the data is read
+ * from the device on demand by sensor_read(), so there is never
+ * anything to wait for.
+ */
- if (filep->f_oflags & O_NONBLOCK)
- {
- eventset |= POLLIN;
- }
- else
- {
- nxsem_get_value(&user->buffersem, &semcount);
- if (semcount > 0)
- {
- eventset |= POLLIN;
- }
- }
+ eventset |= POLLIN;
}
else if (sensor_is_updated(upper, user))
{
@@ -1229,7 +1211,6 @@ static ssize_t sensor_push_event(FAR void *priv, FAR const void *data,
FAR struct sensor_lowerhalf_s *lower = upper->lower;
FAR struct sensor_user_s *user;
unsigned long envcount;
- int semcount;
int ret;
nxrmutex_lock(&upper->lock);
@@ -1287,12 +1268,6 @@ static ssize_t sensor_push_event(FAR void *priv, FAR const void *data,
{
if (sensor_is_updated(upper, user))
{
- nxsem_get_value(&user->buffersem, &semcount);
- if (semcount < 1)
- {
- nxsem_post(&user->buffersem);
- }
-
sensor_pollnotify_one(user, POLLIN, SENSOR_ROLE_RD);
}
}
@@ -1305,17 +1280,10 @@ static void sensor_notify_event(FAR void *priv)
{
FAR struct sensor_upperhalf_s *upper = priv;
FAR struct sensor_user_s *user;
- int semcount;
nxrmutex_lock(&upper->lock);
list_for_every_entry(&upper->userlist, user, struct sensor_user_s, node)
{
- nxsem_get_value(&user->buffersem, &semcount);
- if (semcount < 1)
- {
- nxsem_post(&user->buffersem);
- }
-
sensor_pollnotify_one(user, POLLIN, SENSOR_ROLE_RD);
}
diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h
index e675be50a67..f266eb8cdd3 100644
--- a/include/nuttx/sensors/sensor.h
+++ b/include/nuttx/sensors/sensor.h
@@ -353,10 +353,10 @@ struct sensor_ops_s
* If fetch isn't NULL, upper half driver will disable intermediate
* buffer and userspace can't set buffer size by ioctl.
*
- * You can call this function to read sensor register data by I2C/SPI bus
- * when open mode is non-block, and poll are always successful.
- * When you call this function and open mode is block, you will wait
- * until sensor data ready, then read sensor data.
+ * You can call this function to read sensor register data by I2C/SPI
+ * bus. The data is read from the device on demand, so it is always
+ * available: poll() always reports POLLIN and read() never blocks,
+ * whether or not the open mode is non-block.
*
* Input Parameters:
* lower - The instance of lower half sensor driver.