From 0fd4adef52dee502aeb791100f67ff9fb0bc8ffb Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Fri, 31 Jul 2026 17:48:04 -0300 Subject: [PATCH 1/4] system/uorb: make listener see fetch()-only sensors orb_subscribe_multi() opens the descriptor blocking, so a sensor whose lower half only implements fetch() (no push, e.g. an I2C part with no interrupt line) never satisfies poll()/read() and the listener silently times out with zero messages, indistinguishable from a sensor that has nothing to report. Set O_NONBLOCK after subscribing; sensors that do push samples are unaffected, since neither sensor_poll() nor sensor_read() consults O_NONBLOCK on that path. Signed-off-by: Felipe Moura --- system/uorb/listener.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 2fd1e532d1e..69dbefcff95 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -200,15 +200,31 @@ static int listener_create_dir(FAR char *dir, size_t size) static int listener_subscribe(FAR struct listen_object_s *tmp, bool nonwakeup) { + int flags; + int fd; + if (nonwakeup) { - return orb_subscribe_multi_nonwakeup(tmp->object.meta, - tmp->object.instance); + fd = orb_subscribe_multi_nonwakeup(tmp->object.meta, + tmp->object.instance); } else { - return orb_subscribe_multi(tmp->object.meta, tmp->object.instance); + fd = orb_subscribe_multi(tmp->object.meta, tmp->object.instance); } + + if (fd < 0) + { + return fd; + } + + flags = fcntl(fd, F_GETFL, 0); + if (flags >= 0) + { + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + } + + return fd; } /**************************************************************************** From 2a842d92a2818cc0a2e5551e48c814ecb6ab5191 Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Fri, 31 Jul 2026 17:48:25 -0300 Subject: [PATCH 2/4] system/uorb: honor the requested rate for fetch()-only sensors The upper half accepts SNIOC_SET_INTERVAL and stores it even when the lower half has no set_interval, but only applies it to samples that are pushed into the circular buffer. A fetch()-only sensor was therefore read as fast as the poll loop could run instead of at the rate given with -r. Sleep out the remainder of the period; this is a no-op for sensors where poll() already waited for it. Signed-off-by: Felipe Moura --- system/uorb/listener.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 69dbefcff95..2fd76eeebb3 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -913,6 +913,8 @@ static void listener_monitor(FAR struct listen_list_s *objlist, while ((!nb_msgs || nb_recv_msgs < nb_msgs) && !g_should_exit) { + orb_abstime start = orb_absolute_time(); + if (poll(&fds[0], nb_objects, timeout * 1000) > 0) { i = 0; @@ -955,6 +957,16 @@ static void listener_monitor(FAR struct listen_list_s *objlist, "Giving up. err:%d", timeout, errno); break; } + + if (interval != 0) + { + orb_abstime elapsed = orb_absolute_time() - start; + + if (elapsed < (orb_abstime)interval) + { + usleep((unsigned)((orb_abstime)interval - elapsed)); + } + } } i = 0; From 8551a213aba683f0d6e1c3968f8144115828fae5 Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Fri, 31 Jul 2026 17:48:35 -0300 Subject: [PATCH 3/4] system/uorb: select LIBC_PRINT_EXTENSION for UORB_FORMAT orb_info() is compiled under UORB_FORMAT and formats through the "%pB" extension, but only DEBUG_UORB selected LIBC_PRINT_EXTENSION. Enabling the listener alone therefore printed the raw buffer address instead of the decoded data, e.g. "sensor_accel(now:390000):0x3fc931e4B". Signed-off-by: Felipe Moura --- system/uorb/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/system/uorb/Kconfig b/system/uorb/Kconfig index 71f06e50469..e72ae4f6020 100644 --- a/system/uorb/Kconfig +++ b/system/uorb/Kconfig @@ -20,6 +20,7 @@ config UORB_STACKSIZE config UORB_FORMAT bool + select LIBC_PRINT_EXTENSION default n config UORB_LISTENER From 8724e878a858e03adaf0b95c9ea2a84cb0869a1b Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Fri, 31 Jul 2026 17:48:47 -0300 Subject: [PATCH 4/4] system/uorb: raise default UORB_STACKSIZE for UORB_FORMAT "%pB" nests a second formatting pass, and the listener peaked at 2256 bytes of stack (measured with STACK_COLORATION), which does not fit in a DEFAULT_TASK_STACKSIZE of 2048. The overflow did not fail cleanly: it corrupted memory outside the task, surfacing as an unrelated assertion in another task's mutex. Default to 4096 when UORB_FORMAT is enabled. Signed-off-by: Felipe Moura --- system/uorb/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/system/uorb/Kconfig b/system/uorb/Kconfig index e72ae4f6020..15421c795c5 100644 --- a/system/uorb/Kconfig +++ b/system/uorb/Kconfig @@ -16,7 +16,11 @@ config UORB_PRIORITY config UORB_STACKSIZE int "stack size" + default 4096 if UORB_FORMAT default DEFAULT_TASK_STACKSIZE + ---help--- + UORB_FORMAT needs around 2.2KB of stack for the listener, which + does not fit in a DEFAULT_TASK_STACKSIZE of 2048. config UORB_FORMAT bool