diff --git a/src/modules/uORB/uORBDevices_posix.cpp b/src/modules/uORB/uORBDevices_posix.cpp index 151b6287e8..748e31df4e 100644 --- a/src/modules/uORB/uORBDevices_posix.cpp +++ b/src/modules/uORB/uORBDevices_posix.cpp @@ -287,7 +287,6 @@ uORB::DeviceNode::ioctl(device::file_t *filp, int cmd, unsigned long arg) case ORBIOCSETINTERVAL: sd->update_interval = arg; - sd->last_update = hrt_absolute_time(); return PX4_OK; case ORBIOCGADVERTISER: @@ -406,6 +405,7 @@ uORB::DeviceNode::appears_updated(SubscriberData *sd) * don't match then we might have a visible update. */ while (sd->generation != _generation) { + /* * Handle non-rate-limited subscribers. */ @@ -426,17 +426,31 @@ uORB::DeviceNode::appears_updated(SubscriberData *sd) break; } - // If we have not yet reached the deadline, then assume that we can ignore any - // newly received data. - if (sd->last_update + sd->update_interval > hrt_absolute_time()) { + /* + * If the interval timer is still running, the topic should not + * appear updated, even though at this point we know that it has. + * We have previously been through here, so the subscriber + * must have collected the update we reported, otherwise + * update_reported would still be true. + */ + if (!hrt_called(&sd->update_call)) { break; } + /* + * Make sure that we don't consider the topic to be updated again + * until the interval has passed once more by restarting the interval + * timer and thereby re-scheduling a poll notification at that time. + */ + hrt_call_after(&sd->update_call, + sd->update_interval, + &uORB::DeviceNode::update_deferred_trampoline, + (void *)this); + /* * Remember that we have told the subscriber that there is data. */ sd->update_reported = true; - sd->last_update = hrt_absolute_time(); ret = true; break;