You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/08/01 17:29:11 UTC
[incubator-nuttx] 07/22: driver/sensor: support sensor data persist
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit fa4cebce32e477590bd6c643807e71487436d5f5
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Sat May 21 17:50:29 2022 +0800
driver/sensor: support sensor data persist
Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
drivers/sensors/sensor.c | 29 +++++++++++++++++--
drivers/sensors/sensor_rpmsg.c | 63 +++++++++++++++++++++++++++++++-----------
drivers/sensors/usensor.c | 1 +
include/nuttx/sensors/sensor.h | 17 ++++++++++++
4 files changed, 92 insertions(+), 18 deletions(-)
diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c
index 93fba9e504..89b47813ba 100644
--- a/drivers/sensors/sensor.c
+++ b/drivers/sensors/sensor.c
@@ -426,11 +426,23 @@ static int sensor_open(FAR struct file *filep)
if (filep->f_oflags & O_WROK)
{
upper->state.nadvertisers++;
+ if (filep->f_oflags & SENSOR_PERSIST)
+ {
+ lower->persist = true;
+ }
+ }
+
+ if (upper->state.generation && lower->persist)
+ {
+ user->generation = upper->state.generation - 1;
+ }
+ else
+ {
+ user->generation = upper->state.generation;
}
user->interval = ULONG_MAX;
user->latency = ULONG_MAX;
- user->generation = upper->state.generation;
user->readlast = true;
nxsem_init(&user->buffersem, 0, 0);
nxsem_set_protocol(&user->buffersem, SEM_PRIO_NONE);
@@ -556,9 +568,22 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
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)
{
- user->generation--;
+ if (lower->persist)
+ {
+ user->generation--;
+ }
+ else
+ {
+ ret = -ENODATA;
+ goto out;
+ }
}
}
else
diff --git a/drivers/sensors/sensor_rpmsg.c b/drivers/sensors/sensor_rpmsg.c
index 1b2a1176cd..58ba632c7d 100644
--- a/drivers/sensors/sensor_rpmsg.c
+++ b/drivers/sensors/sensor_rpmsg.c
@@ -37,8 +37,6 @@
* Pre-processor Definitions
****************************************************************************/
-#define O_REMOTE (1 << 31)
-
#define SENSOR_RPMSG_EPT_NAME "rpmsg-sensor"
#define SENSOR_RPMSG_ADVERTISE 0
#define SENSOR_RPMSG_ADVERTISE_ACK 1
@@ -63,7 +61,7 @@ static int sensor_rpmsg_##name(FAR struct file *filep, \
{ \
return drv->ops->name(filep, drv, arg2); \
} \
- else if (!(filep->f_oflags & O_REMOTE)) \
+ else if (!(filep->f_oflags & SENSOR_REMOTE)) \
{ \
ret = sensor_rpmsg_ioctl(dev, cmd, arg1, size, wait); \
return wait ? ret : 0; \
@@ -140,6 +138,7 @@ struct sensor_rpmsg_advsub_s
uint32_t command;
uint32_t nbuffer;
uint64_t cookie;
+ uint32_t persist;
char path[1];
};
@@ -245,6 +244,8 @@ static int sensor_rpmsg_ioctl_handler(FAR struct rpmsg_endpoint *ept,
static int sensor_rpmsg_ioctlack_handler(FAR struct rpmsg_endpoint *ept,
FAR void *data, size_t len,
uint32_t src, FAR void *priv);
+static void sensor_rpmsg_push_event_one(FAR struct sensor_rpmsg_dev_s *dev,
+ FAR struct sensor_rpmsg_stub_s *stub);
/****************************************************************************
* Private Data
@@ -304,6 +305,7 @@ static void sensor_rpmsg_advsub_one(FAR struct sensor_rpmsg_dev_s *dev,
msg->command = command;
msg->cookie = (uint64_t)(uintptr_t)dev;
msg->nbuffer = dev->lower.nbuffer;
+ msg->persist = dev->lower.persist;
memcpy(msg->path, dev->path, len);
ret = rpmsg_send_nocopy(ept, msg, sizeof(*msg) + len);
if (ret < 0)
@@ -418,13 +420,22 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev,
static FAR struct sensor_rpmsg_proxy_s *
sensor_rpmsg_alloc_proxy(FAR struct sensor_rpmsg_dev_s *dev,
FAR struct rpmsg_endpoint *ept,
- uint64_t cookie, uint32_t nbuffer)
+ FAR struct sensor_rpmsg_advsub_s *msg)
{
FAR struct sensor_rpmsg_proxy_s *proxy;
struct sensor_state_s state;
struct file file;
int ret;
+ list_for_every_entry(&dev->proxylist, proxy,
+ struct sensor_rpmsg_proxy_s, node)
+ {
+ if (proxy->ept == ept && proxy->cookie == msg->cookie)
+ {
+ return proxy;
+ }
+ }
+
/* Create new proxy to represent a remote advertiser */
proxy = kmm_malloc(sizeof(*proxy));
@@ -434,19 +445,25 @@ sensor_rpmsg_alloc_proxy(FAR struct sensor_rpmsg_dev_s *dev,
}
proxy->ept = ept;
- proxy->cookie = cookie;
- ret = file_open(&file, dev->path, O_REMOTE);
+ proxy->cookie = msg->cookie;
+ ret = file_open(&file, dev->path, SENSOR_REMOTE);
if (ret < 0)
{
kmm_free(proxy);
return NULL;
}
- file_ioctl(&file, SNIOC_SET_BUFFER_NUMBER, nbuffer);
+ file_ioctl(&file, SNIOC_SET_BUFFER_NUMBER, msg->nbuffer);
file_ioctl(&file, SNIOC_GET_STATE, &state);
file_close(&file);
nxmutex_lock(&dev->lock);
+ if (msg->persist)
+ {
+ dev->drv->persist = true;
+ dev->lower.persist = true;
+ }
+
list_add_tail(&dev->proxylist, &proxy->node);
nxmutex_unlock(&dev->lock);
@@ -474,6 +491,15 @@ sensor_rpmsg_alloc_stub(FAR struct sensor_rpmsg_dev_s *dev,
FAR struct sensor_rpmsg_stub_s *stub;
int ret;
+ list_for_every_entry(&dev->stublist, stub,
+ struct sensor_rpmsg_stub_s, node)
+ {
+ if (stub->ept == ept && stub->cookie == cookie)
+ {
+ return stub;
+ }
+ }
+
/* Create new stub to represent a remote subscribers */
stub = kmm_malloc(sizeof(*stub));
@@ -485,7 +511,7 @@ sensor_rpmsg_alloc_stub(FAR struct sensor_rpmsg_dev_s *dev,
stub->ept = ept;
stub->cookie = cookie;
ret = file_open(&stub->file, dev->path,
- O_RDOK | O_NONBLOCK | O_REMOTE);
+ O_RDOK | O_NONBLOCK | SENSOR_REMOTE);
if (ret < 0)
{
kmm_free(stub);
@@ -497,6 +523,11 @@ sensor_rpmsg_alloc_stub(FAR struct sensor_rpmsg_dev_s *dev,
list_add_tail(&dev->stublist, &stub->node);
nxmutex_unlock(&dev->lock);
+ if (dev->lower.persist)
+ {
+ sensor_rpmsg_push_event_one(dev, stub);
+ }
+
return stub;
}
@@ -529,7 +560,7 @@ static int sensor_rpmsg_open(FAR struct file *filep,
}
}
- if (filep->f_oflags & O_REMOTE)
+ if (filep->f_oflags & SENSOR_REMOTE)
{
return 0;
}
@@ -571,7 +602,7 @@ static int sensor_rpmsg_close(FAR struct file *filep,
ret = drv->ops->close(filep, drv);
}
- if (filep->f_oflags & O_REMOTE)
+ if (filep->f_oflags & SENSOR_REMOTE)
{
return ret;
}
@@ -646,7 +677,7 @@ static int sensor_rpmsg_control(FAR struct file *filep,
{
return drv->ops->control(filep, drv, cmd, arg);
}
- else if (!(filep->f_oflags & O_REMOTE) && _SNIOCVALID(cmd))
+ else if (!(filep->f_oflags & SENSOR_REMOTE) && _SNIOCVALID(cmd))
{
return sensor_rpmsg_ioctl(dev, cmd, arg,
sizeof(*ioctl) + ioctl->len, true);
@@ -838,7 +869,7 @@ static int sensor_rpmsg_adv_handler(FAR struct rpmsg_endpoint *ept,
return 0;
}
- proxy = sensor_rpmsg_alloc_proxy(dev, ept, msg->cookie, msg->nbuffer);
+ proxy = sensor_rpmsg_alloc_proxy(dev, ept, msg);
if (!proxy)
{
snerr("ERROR: adv alloc proxy failed:%s\n", dev->path);
@@ -866,8 +897,7 @@ static int sensor_rpmsg_advack_handler(FAR struct rpmsg_endpoint *ept,
FAR struct sensor_rpmsg_dev_s *dev;
dev = sensor_rpmsg_find_dev(msg->path);
- if (dev && (!dev->nadvertisers ||
- !sensor_rpmsg_alloc_stub(dev, ept, msg->cookie)))
+ if (dev && !sensor_rpmsg_alloc_stub(dev, ept, msg->cookie))
{
sensor_rpmsg_advsub_one(dev, ept, SENSOR_RPMSG_UNADVERTISE);
snerr("ERROR: advack failed:%s\n", dev->path);
@@ -915,7 +945,7 @@ static int sensor_rpmsg_sub_handler(FAR struct rpmsg_endpoint *ept,
int ret;
dev = sensor_rpmsg_find_dev(msg->path);
- if (!dev || !dev->nadvertisers)
+ if (!dev)
{
return 0;
}
@@ -930,6 +960,7 @@ static int sensor_rpmsg_sub_handler(FAR struct rpmsg_endpoint *ept,
msg->cookie = (uint64_t)(uintptr_t)dev;
msg->command = SENSOR_RPMSG_SUBSCRIBE_ACK;
msg->nbuffer = dev->lower.nbuffer;
+ msg->persist = dev->lower.persist;
ret = rpmsg_send(ept, msg, len);
if (ret < 0)
{
@@ -950,7 +981,7 @@ static int sensor_rpmsg_suback_handler(FAR struct rpmsg_endpoint *ept,
dev = sensor_rpmsg_find_dev(msg->path);
if (dev && (!dev->nsubscribers ||
- !sensor_rpmsg_alloc_proxy(dev, ept, msg->cookie, msg->nbuffer)))
+ !sensor_rpmsg_alloc_proxy(dev, ept, msg)))
{
sensor_rpmsg_advsub_one(dev, ept, SENSOR_RPMSG_UNSUBSCRIBE);
snerr("ERROR: suback failed:%s\n", dev->path);
diff --git a/drivers/sensors/usensor.c b/drivers/sensors/usensor.c
index ef203b51f4..a011b9a7f2 100644
--- a/drivers/sensors/usensor.c
+++ b/drivers/sensors/usensor.c
@@ -105,6 +105,7 @@ static int usensor_register(FAR struct usensor_context_s *usensor,
}
lower->driver.nbuffer = info->nbuffer;
+ lower->driver.persist = info->persist;
lower->driver.ops = &g_usensor_ops;
strcpy(lower->path, info->path);
ret = sensor_custom_register(&lower->driver, lower->path, info->esize);
diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h
index ef0f2442a3..35172a6080 100644
--- a/include/nuttx/sensors/sensor.h
+++ b/include/nuttx/sensors/sensor.h
@@ -293,6 +293,11 @@
#define SENSOR_TYPE_COUNT 33
+/* The additional sensor open flags */
+
+#define SENSOR_REMOTE (1 << 31)
+#define SENSOR_PERSIST (1 << 30)
+
/****************************************************************************
* Inline Functions
****************************************************************************/
@@ -935,6 +940,12 @@ struct sensor_lowerhalf_s
/* The private opaque pointer to be passed to upper-layer during callback */
FAR void *priv;
+
+ /* The flag is used to indicate that the validity of sensor data is
+ * persistent, such as battery status information, switch information, etc.
+ */
+
+ bool persist;
};
/* This structure describes the state for the sensor device */
@@ -959,6 +970,12 @@ struct sensor_reginfo_s
FAR const char *path; /* The path of user sensor */
unsigned long esize; /* The element size of user sensor */
unsigned long nbuffer; /* The number of queue buffered elements */
+
+ /* The flag is used to indicate that the validity of sensor data
+ * is persistent.
+ */
+
+ bool persist;
};
#endif