diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index e4e67ec5fc611..077a43f40cb30 100644 --- a/drivers/sensors/sensor.c +++ b/drivers/sensors/sensor.c @@ -445,38 +445,41 @@ static int sensor_update_latency(FAR struct file *filep, return ret; } -static void sensor_update_nonwakeup(FAR struct file *filep, - FAR struct sensor_upperhalf_s *upper, - FAR struct sensor_user_s *user, - bool nonwakeup) +static void sensor_update_wakeup(FAR struct file *filep, + FAR struct sensor_upperhalf_s *upper, + FAR struct sensor_user_s *user, + bool wakeup) { FAR struct sensor_lowerhalf_s *lower = upper->lower; - if (nonwakeup == user->state.nonwakeup) + if (wakeup == user->state.wakeup) { return; } - user->state.nonwakeup = nonwakeup; + sminfo(upper->name, "update wakeup:%d, user:%d, upper:%d", wakeup, + user->state.wakeup, upper->state.wakeup); + user->state.wakeup = wakeup; nxrmutex_lock(&upper->lock); list_for_every_entry(&upper->userlist, user, struct sensor_user_s, node) { - if (!user->state.nonwakeup) + if (user->state.wakeup) { - nonwakeup = false; + wakeup = true; break; } } - if (nonwakeup != upper->state.nonwakeup) + sminfo(upper->name, "change status, wakeup:%d, upper:%d", + wakeup, upper->state.wakeup); + if (wakeup != upper->state.wakeup) { - upper->state.nonwakeup = nonwakeup; - sminfo(upper->name, "update nonwakeup %d", nonwakeup); + upper->state.wakeup = wakeup; nxrmutex_unlock(&upper->lock); - if (lower->ops->set_nonwakeup) + if (lower->ops->set_wakeup) { - lower->ops->set_nonwakeup(lower, filep, nonwakeup); + lower->ops->set_wakeup(lower, filep, wakeup); } } else @@ -773,7 +776,7 @@ static int sensor_open(FAR struct file *filep) user->state.interval = UINT32_MAX; user->state.esize = upper->state.esize; - user->state.nonwakeup = true; + user->state.wakeup = false; nxsem_init(&user->buffersem, 0, 0); list_add_tail(&upper->userlist, &user->node); @@ -807,7 +810,7 @@ static int sensor_close(FAR struct file *filep) sensor_update_interval(filep, upper, user, UINT32_MAX); sensor_update_latency(filep, upper, user, UINT32_MAX); - sensor_update_nonwakeup(filep, upper, user, true); + sensor_update_wakeup(filep, upper, user, false); nxrmutex_lock(&upper->lock); @@ -1027,9 +1030,9 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; - case SNIOC_SET_NONWAKEUP: + case SNIOC_SET_WAKEUP: { - sensor_update_nonwakeup(filep, upper, user, (bool)arg); + sensor_update_wakeup(filep, upper, user, (bool)arg); } break; @@ -1455,7 +1458,7 @@ int sensor_custom_register(FAR struct sensor_lowerhalf_s *lower, list_initialize(&upper->userlist); upper->state.esize = esize; upper->state.min_interval = UINT32_MAX; - upper->state.nonwakeup = true; + upper->state.wakeup = false; if (lower->ops->activate) { upper->state.nadvertisers = 1; diff --git a/drivers/sensors/sensor_rpmsg.c b/drivers/sensors/sensor_rpmsg.c index 99b3f0bc03bd1..b39c48d07ede3 100644 --- a/drivers/sensors/sensor_rpmsg.c +++ b/drivers/sensors/sensor_rpmsg.c @@ -125,7 +125,7 @@ struct sensor_rpmsg_stub_s uint64_t cookie; struct file file; bool flushing; - bool nonwakeup; + bool wakeup; }; /* This structure describes the proxy info about remote advertisers. */ @@ -135,6 +135,7 @@ struct sensor_rpmsg_proxy_s struct list_node node; FAR struct rpmsg_endpoint *ept; uint64_t cookie; + bool wakeup; }; /* Remote message structure */ @@ -230,9 +231,9 @@ static int sensor_rpmsg_calibrate(FAR struct sensor_lowerhalf_s *lower, static int sensor_rpmsg_get_info(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, FAR struct sensor_device_info_s *info); -static int sensor_rpmsg_set_nonwakeup(FAR struct sensor_lowerhalf_s *lower, - FAR struct file *filep, - bool nonwakeup); +static int sensor_rpmsg_set_wakeup(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + bool wakeup); static int sensor_rpmsg_control(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg); @@ -280,7 +281,7 @@ static const struct sensor_ops_s g_sensor_rpmsg_ops = .set_calibvalue = sensor_rpmsg_set_calibvalue, .calibrate = sensor_rpmsg_calibrate, .get_info = sensor_rpmsg_get_info, - .set_nonwakeup = sensor_rpmsg_set_nonwakeup, + .set_wakeup = sensor_rpmsg_set_wakeup, .control = sensor_rpmsg_control }; @@ -358,7 +359,50 @@ static void sensor_rpmsg_advsub(FAR struct sensor_rpmsg_dev_s *dev, list_for_every_entry(&g_eptlist, sre, struct sensor_rpmsg_ept_s, node) { - sensor_rpmsg_advsub_one(dev, &sre->ept, command); + FAR struct sensor_rpmsg_proxy_s *proxy = NULL; + bool find = false; + + if (command == SENSOR_RPMSG_SUBSCRIBE || + command == SENSOR_RPMSG_UNSUBSCRIBE) + { + /* If it has been bound before, do not send. */ + + list_for_every_entry(&dev->proxylist, proxy, + struct sensor_rpmsg_proxy_s, node) + { + if (proxy->ept == &sre->ept) + { + find = true; + break; + } + } + } + + /* There are several scenarios that require broadcasting: + * 1. If the proxy corresponding to the EPT (Endpoint) did not + * exist previously, this constitutes the first broadcast. + * 2. If the proxy previously had a wakeup attribute, it should + * be broadcast every time. + * 3. If the proxy does not have the wakeup attribute and the + * target core is in the running state, we should still broadcast + * it. + * + * In summary, Let's avoid broadcasting non-wakeup sensors when the + * target core is in a sleep state to prevent unnecessary wakeups. + */ + + if (rpmsg_is_running(sre->ept.rdev) || (find && proxy->wakeup)) + { + sensor_rpmsg_advsub_one(dev, &sre->ept, command); + } + else + { + sninfo("INFO: advsub:%d %s ignore broadcast to %s, " + "as %d, %d, %d\n", + command, dev->path, rpmsg_get_cpuname(sre->ept.rdev), + find, proxy ? proxy->wakeup : 0, + rpmsg_is_running(sre->ept.rdev)); + } } up_read(&g_ept_lock); @@ -411,6 +455,15 @@ static int sensor_rpmsg_ioctl(FAR struct sensor_rpmsg_dev_s *dev, list_for_every_entry_safe(&dev->proxylist, proxy, ptmp, struct sensor_rpmsg_proxy_s, node) { + /* Check whether the proxy has been set to the wakeup state + * before. If it has, record it. + */ + + if (cmd == SNIOC_SET_WAKEUP) + { + proxy->wakeup = arg; + } + ept = proxy->ept; pcookie = proxy->cookie; msg = rpmsg_get_tx_payload_buffer(ept, &space, true); @@ -509,6 +562,7 @@ sensor_rpmsg_alloc_proxy(FAR struct sensor_rpmsg_dev_s *dev, proxy->ept = ept; proxy->cookie = msg->cookie; + proxy->wakeup = false; ret = file_open(&file, dev->path, SENSOR_REMOTE | O_CLOEXEC); if (ret < 0) { @@ -663,6 +717,8 @@ static int sensor_rpmsg_open(FAR struct sensor_lowerhalf_s *lower, { FAR struct sensor_rpmsg_dev_s *dev = lower->priv; FAR struct sensor_lowerhalf_s *drv = dev->drv; + bool adv = false; + bool sub = false; int ret; if (drv->ops->open) @@ -684,19 +740,35 @@ static int sensor_rpmsg_open(FAR struct sensor_lowerhalf_s *lower, { if (dev->nadvertisers++ == 0) { - sensor_rpmsg_advsub(dev, SENSOR_RPMSG_ADVERTISE); + adv = true; } } if (filep->f_oflags & O_RDOK) { - if (dev->nsubscribers++ == 0) + /* Send broadcast subscribed info if dev isn't + * physical sensor to avoid waking up remote core. + */ + + if (dev->nsubscribers++ == 0 && + drv->ops->activate == NULL) { - sensor_rpmsg_advsub(dev, SENSOR_RPMSG_SUBSCRIBE); + sub = true; } } sensor_rpmsg_unlock(dev); + + if (adv) + { + sensor_rpmsg_advsub(dev, SENSOR_RPMSG_ADVERTISE); + } + + if (sub) + { + sensor_rpmsg_advsub(dev, SENSOR_RPMSG_SUBSCRIBE); + } + return 0; } @@ -705,10 +777,9 @@ static int sensor_rpmsg_close(FAR struct sensor_lowerhalf_s *lower, { FAR struct sensor_rpmsg_dev_s *dev = lower->priv; FAR struct sensor_lowerhalf_s *drv = dev->drv; - FAR struct sensor_rpmsg_proxy_s *proxy; - FAR struct sensor_rpmsg_proxy_s *ptmp; FAR struct sensor_rpmsg_stub_s *stub; FAR struct sensor_rpmsg_stub_s *stmp; + bool unsub = false; int ret = 0; if (drv->ops->close) @@ -726,7 +797,6 @@ static int sensor_rpmsg_close(FAR struct sensor_lowerhalf_s *lower, { if (dev->nadvertisers == 1) { - sensor_rpmsg_advsub(dev, SENSOR_RPMSG_UNADVERTISE); list_for_every_entry_safe(&dev->stublist, stub, stmp, struct sensor_rpmsg_stub_s, node) { @@ -739,20 +809,26 @@ static int sensor_rpmsg_close(FAR struct sensor_lowerhalf_s *lower, if (filep->f_oflags & O_RDOK) { - if (dev->nsubscribers == 1) + /* Send broadcast unsubscribed info if dev isn't + * physical sensor to avoid waking up remote core. + */ + + if (dev->nsubscribers == 1 && + drv->ops->activate == NULL) { - sensor_rpmsg_advsub(dev, SENSOR_RPMSG_UNSUBSCRIBE); - list_for_every_entry_safe(&dev->proxylist, proxy, ptmp, - struct sensor_rpmsg_proxy_s, node) - { - sensor_rpmsg_free_proxy(dev, proxy); - } + unsub = true; } dev->nsubscribers--; } sensor_rpmsg_unlock(dev); + + if (unsub) + { + sensor_rpmsg_advsub(dev, SENSOR_RPMSG_UNSUBSCRIBE); + } + return ret; } @@ -814,24 +890,25 @@ static int sensor_rpmsg_flush(FAR struct sensor_lowerhalf_s *lower, return ret; } -static int sensor_rpmsg_set_nonwakeup(FAR struct sensor_lowerhalf_s *lower, - FAR struct file *filep, - bool nonwakeup) +static int sensor_rpmsg_set_wakeup(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, + bool wakeup) { FAR struct sensor_rpmsg_dev_s *dev = lower->priv; FAR struct sensor_lowerhalf_s *drv = dev->drv; int ret = -ENOTTY; - if (drv->ops->set_nonwakeup) + sminfo(dev->name, "rpsmg set wakeup status:%d", wakeup); + if (drv->ops->set_wakeup) { - ret = drv->ops->set_nonwakeup(drv, filep, nonwakeup); + ret = drv->ops->set_wakeup(drv, filep, wakeup); } else if ((filep->f_oflags & SENSOR_REMOTE) || dev->nadvertisers > 0) { - /* If the driver (drv) does not support the nonwakeup operation, + /* If the driver (drv) does not support the wakeup operation, * and the caller is a remote invocation or the current device - * is an advertiser, then you can still consider the nonwakeup + * is an advertiser, then you can still consider the wakeup * operation as unsupported and therefore return ENOTSUP */ @@ -839,8 +916,9 @@ static int sensor_rpmsg_set_nonwakeup(FAR struct sensor_lowerhalf_s *lower, } else { - ret = sensor_rpmsg_ioctl(dev, SNIOC_SET_NONWAKEUP, - nonwakeup, 0, true); + sminfo(dev->name, "rpsmg set wakeup to remote core:%d", wakeup); + ret = sensor_rpmsg_ioctl(dev, SNIOC_SET_WAKEUP, + wakeup, 0, true); } return ret; @@ -929,7 +1007,7 @@ static void sensor_rpmsg_push_event_one(FAR struct sensor_rpmsg_dev_s *dev, */ sre = container_of(stub->ept, struct sensor_rpmsg_ept_s, ept); - if (stub->nonwakeup && !rpmsg_is_running(sre->ept.rdev)) + if (!stub->wakeup && !rpmsg_is_running(sre->ept.rdev)) { return; } @@ -1129,9 +1207,6 @@ static int sensor_rpmsg_adv_handler(FAR struct rpmsg_endpoint *ept, ret = rpmsg_send(ept, msg, len); if (ret < 0) { - sensor_rpmsg_lock(dev); - sensor_rpmsg_free_proxy(dev, proxy); - sensor_rpmsg_unlock(dev); snerr("ERROR: adv rpmsg send failed:%s, %d, %s\n", dev->path, ret, rpmsg_get_cpuname(ept->rdev)); } @@ -1153,7 +1228,6 @@ static int sensor_rpmsg_advack_handler(FAR struct rpmsg_endpoint *ept, dev = sensor_rpmsg_find_dev(msg->path); if (dev && !sensor_rpmsg_alloc_stub(dev, ept, msg->cookie)) { - sensor_rpmsg_advsub_one(dev, ept, SENSOR_RPMSG_UNADVERTISE); snerr("ERROR: advack failed:%s, %s\n", dev->path, rpmsg_get_cpuname(ept->rdev)); } @@ -1165,30 +1239,6 @@ static int sensor_rpmsg_unadv_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv) { - FAR struct sensor_rpmsg_advsub_s *msg = data; - FAR struct sensor_rpmsg_proxy_s *proxy; - FAR struct sensor_rpmsg_dev_s *dev; - - dev = sensor_rpmsg_find_dev(msg->path); - if (!dev) - { - return 0; - } - - sensor_rpmsg_lock(dev); - list_for_every_entry(&dev->proxylist, proxy, - struct sensor_rpmsg_proxy_s, node) - { - if (proxy->ept == ept && proxy->cookie == msg->cookie) - { - sensor_rpmsg_free_proxy(dev, proxy); - sminfo(dev->name, "rpmsg unadv free proxy success, " - "remote:%s", rpmsg_get_cpuname(ept->rdev)); - break; - } - } - - sensor_rpmsg_unlock(dev); return 0; } @@ -1372,9 +1422,10 @@ static int sensor_rpmsg_ioctl_handler(FAR struct rpmsg_endpoint *ept, stub->flushing = true; } - if (msg->request == SNIOC_SET_NONWAKEUP) + if (msg->request == SNIOC_SET_WAKEUP) { - stub->nonwakeup = arg; + stub->wakeup = arg; + sminfo(dev->name, "receiving wakeup update:%d", stub->wakeup); } if (msg->cookie) diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h index 5cc397f76debd..cab63d3ccd7b4 100644 --- a/include/nuttx/sensors/ioctl.h +++ b/include/nuttx/sensors/ioctl.h @@ -502,12 +502,12 @@ #define SNIOC_COLD_START _SNIOC(0X00A7) #define SNIOC_FULL_COLD_START _SNIOC(0X00A8) -/* Command: SNIOC_SET_NONWAKEUP - * Description: Set non-wakeup flag for user. - * Argument: True is non-wakeup, false is wakeup. +/* Command: SNIOC_SET_WAKEUP + * Description: Set wakeup flag for user. + * Argument: True is wakeup, false is non-wakeup. */ -#define SNIOC_SET_NONWAKEUP _SNIOC(0x00A9) +#define SNIOC_SET_WAKEUP _SNIOC(0x00A9) /**************************************************************************** * Public types diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h index 33094f46dc099..0f472f84967ab 100644 --- a/include/nuttx/sensors/sensor.h +++ b/include/nuttx/sensors/sensor.h @@ -500,23 +500,23 @@ struct sensor_ops_s FAR struct sensor_device_info_s *info); /************************************************************************** - * Name: set_nonwakeup + * Name: set_wakeup * - * With this method, the user can disable wakeup capacity for the sensor - * when data or fifo ready to avoid wakeup cpu, and save power. + * With this method, the user can enable wakeup capacity for the sensor + * when data or fifo ready to wakeup cpu. * * Input Parameters: * lower - The instance of lower half sensor driver. * filep - The pointer of file, represents each user using sensor. - * nonwakeup - true(nonwakeup) and false(wakeup) + * wakeup - true(wakeup) and false(non-wakeup) * * Returned Value: * Zero (OK) on success; a negated errno value on failure. * **************************************************************************/ - CODE int (*set_nonwakeup)(FAR struct sensor_lowerhalf_s *lower, - FAR struct file *filep, bool nonwakeup); + CODE int (*set_wakeup)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, bool wakeup); /************************************************************************** * Name: control diff --git a/include/nuttx/uorb.h b/include/nuttx/uorb.h index 4db10dce60131..cb3d8ffbb03b4 100644 --- a/include/nuttx/uorb.h +++ b/include/nuttx/uorb.h @@ -1245,7 +1245,7 @@ struct sensor_state_s uint32_t nsubscribers; /* The number of subscribers */ uint32_t nadvertisers; /* The number of advertisers */ uint32_t generation; /* The recent generation of circular buffer */ - uint32_t nonwakeup; /* The non wakeup state of sensor device */ + uint32_t wakeup; /* The wakeup state of sensor device */ uint64_t priv; /* The pointer to private data of userspace user */ }; @@ -1256,7 +1256,7 @@ struct sensor_ustate_s uint32_t esize; /* The element size of circular buffer */ uint32_t latency; /* The batch latency for user, in us */ uint32_t interval; /* The subscription interval for user, in us */ - uint32_t nonwakeup; /* The non wakeup state of sensor user */ + uint32_t wakeup; /* The wakeup state of sensor user */ uint32_t generation; /* The recent generation of circular buffer */ };