Skip to content

system/microros: Add UDP and serial custom transports with publisher example#3512

Open
arjav1528 wants to merge 4 commits into
apache:masterfrom
arjav1528:micro-ros-custom-transport
Open

system/microros: Add UDP and serial custom transports with publisher example#3512
arjav1528 wants to merge 4 commits into
apache:masterfrom
arjav1528:micro-ros-custom-transport

Conversation

@arjav1528
Copy link
Copy Markdown
Contributor

@arjav1528 arjav1528 commented May 30, 2026

Phase 4 of micro-ROS-on-NuttX. Adds the transport callbacks Micro
XRCE-DDS needs and a minimal publisher example. Split into 4 commits:

  1. system/microros: Fix toolchain attribute strip breaking libc inlines.
    Drop -D'__attribute__(x)=' from toolchain.cmake.in. The strip
    also removed __gnu_inline__ from NuttX libc string.h inlines,
    causing ~50 multiple-definition errors at sim final link.
  2. system/microros: Wire libmicroros include layout and sim final link.
    Enumerate include/* subdirs so both <rcl/rcl.h> (nested colcon
    layout) and <rclc/rclc.h> (flat) resolve. Switch LDLIBS
    EXTRA_LIBS so the sim final link picks up libmicroros.a.
  3. system/microros: Add UDP and serial custom transport backends.
    New transport/ dispatcher + UDP (BSD sockets, unconnected
    sendto/recvfrom so host-mode docker agent replies are accepted)
    • serial (termios, raw 8N1). Wired into Make and CMake
      (cmake-format clean).
  4. examples/microros_pub: Add minimal Int32 publisher example.
    30 std_msgs/Int32 messages on /nuttx_pub at 1 Hz, then clean
    fini. Smoke test for the transport layer.

Impact

  • Fixes a pre-existing sim final-link regression in system/microros
    (apps/system/microros: add libmicroros.a colcon cross-build orchestration #3498); any non-trivial micro-ROS sim build was broken before this.
  • New Kconfig: MICROROS_TRANSPORT_{UDP,SERIAL}, MICROROS_AGENT_IP,
    MICROROS_AGENT_PORT, MICROROS_SERIAL_DEVICE,
    MICROROS_SERIAL_BAUD. Default off — no change for existing configs.
  • UDP backend needs CONFIG_NET_UDP; serial backend needs a TTY.

Dependencies

Depends on companion nuttx PR
[tools/nxstyle: Whitelist ROS 2 message type identifiers.]
(branch tools-nxstyle-microros-whitelist). Without it, nxstyle
flags two unavoidable mixed-case identifiers in
examples/microros_pub/microros_pub_main.c
(std_msgs__msg__Int32 and the Int32 macro arg to
ROSIDL_GET_MSG_TYPE_SUPPORT) — both are upstream rosidl
token-pasted symbols that cannot be renamed.

Testing

Ubuntu 22.04 EC2, sim:nsh + CONFIG_SYSTEM_MICROROS=y +
MICROROS_TRANSPORT_UDP=y + EXAMPLES_MICROROS_PUB=y. TAP
networking, host 192.168.10.1, NuttX 192.168.10.2. Agent
micro-ros/micro-ros-agent:jazzy in docker --network host, UDP4
port 8888.

phase3.log
phase4_agent.log
phase4_bootstrap.log
phase4_make_context.log

  • phase4.log — NSH session, 30/30 publishes + done.
  • phase4_agent.log — session establish, publisher create, 30 ACKs,
    clean destroy.
  • phase4_bootstrap.log, phase4_make_context.log — build.

Excerpt:

nsh> microros_pub
microros_pub: starting
microros_pub: sent 0
...
microros_pub: sent 29
microros_pub: done

nxstyle (with companion patch applied) clean on all 8 touched
C/H files. cmake-format clean on system/microros/CMakeLists.txt.

Not verified: serial backend on hardware — I dont have the
hardware needed.

@acassis
Copy link
Copy Markdown
Contributor

acassis commented May 30, 2026

@arjav1528 after apache/nuttx#19001 get merged, please rebase to git push -f to fix the CI Check error.

@arjav1528
Copy link
Copy Markdown
Contributor Author

@arjav1528 after apache/nuttx#19001 get merged, please rebase to git push -f to fix the CI Check error.

ya, sure, thats what I was gonna do

Comment thread examples/microros_pub/Kconfig Outdated

config EXAMPLES_MICROROS_PUB_STACKSIZE
int "micro-ROS pub stack size"
default 16384
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need so big stack

****************************************************************************/

static rcl_publisher_t g_publisher;
static std_msgs__msg__Int32 g_msg;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to local variables

@@ -0,0 +1,32 @@
############################################################################
# apps/examples/microros_pub/Makefile
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add cmake build file

#if defined(CONFIG_MICROROS_TRANSPORT_UDP)
rmw_uros_set_custom_transport(false,
NULL,
(open_custom_func)microros_udp_open,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ALL cast

(write_custom_func)microros_udp_write,
(read_custom_func)microros_udp_read);
return 0;
#elif defined(CONFIG_MICROROS_TRANSPORT_SERIAL)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can/should we support the multiple transport at the same time

return 0;
}

return (size_t)n;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the cast

return 0;
}

return (size_t)n;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove too

Comment thread system/microros/Make.defs Outdated
MICROROS_INC_DIRS := $(APPDIR)/system/microros/include \
$(wildcard $(APPDIR)/system/microros/include/*)
CFLAGS += $(foreach d,$(MICROROS_INC_DIRS),${INCDIR_PREFIX}$(d))
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/transport
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to Makefile to avoid expose $(APPDIR)/system/microros/transport to public search path

Comment thread system/microros/Make.defs Outdated
CFLAGS += $(foreach d,$(MICROROS_INC_DIRS),${INCDIR_PREFIX}$(d))
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/transport
CXXFLAGS += $(foreach d,$(MICROROS_INC_DIRS),${INCDIR_PREFIX}$(d))
CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/transport
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Comment thread system/microros/Make.defs

CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include
CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include
MICROROS_INC_DIRS := $(APPDIR)/system/microros/include \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge to previous patch

arjav1528 added 4 commits May 31, 2026 10:11
micro_ros_lib/toolchain.cmake.in initialised C and CXX flags with
-D'__attribute__(x)=' to silence GCC attributes the upstream ament
build is not aware of. The strip also removed __gnu_inline__ and
__always_inline__ from NuttX's libc string.h inlines, so each
micro-ROS translation unit emitted external definitions of strcmp,
strcpy, strlen and friends. Sim final link then failed with ~50
multiple-definition errors.

Drop the define from both flag init lines so the attributes survive
and the inlines collapse as intended.

Signed-off-by: Arjav Patel <arjav1528@gmail.com>
libmicroros is installed by colcon under include/<pkg>/<pkg>/file.h
for ament-packaged headers (e.g. rcl, rmw, rosidl) and the flat
include/<pkg>/file.h for a few others (e.g. rclc). A single
-I include/ therefore resolves <rclc/rclc.h> but not <rcl/rcl.h>.

Enumerate every immediate subdirectory of include/ in addition to
include/ itself so both layouts resolve.

Switch the library hand-off from LDLIBS to EXTRA_LIBS. The sim
target's final link pulls EXTRA_LIBS, not LDLIBS, so the previous
form left rcl/rclc/rcutils symbols unresolved.

Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Micro XRCE-DDS expects the application to supply open/close/write/read
callbacks for the wire transport. Add a single dispatcher that
registers the selected backend via rmw_uros_set_custom_transport(),
plus two backends:

transport/microros_transport_udp.c
  BSD-socket UDP backend. Opens an AF_INET/SOCK_DGRAM socket,
  resolves CONFIG_MICROROS_AGENT_IP/PORT, connect()s it, and uses
  send/recv. The socket fd is stashed in uxrCustomTransport->args
  so no module-level state is needed.

transport/microros_transport_serial.c
  termios serial backend. Opens CONFIG_MICROROS_SERIAL_DEVICE with
  O_RDWR|O_NOCTTY|O_CLOEXEC, switches to raw 8N1 at
  CONFIG_MICROROS_SERIAL_BAUD, and uses poll/read/write. Fd is
  again stashed in uxrCustomTransport->args.

Both backends are mutually exclusive at compile time via Kconfig;
the dispatcher selects which set of callbacks to register. Wired
into both the legacy Make build (CSRCS in system/microros/Makefile)
and the CMake build (separate microros_transport static library
with the transport directory only exposed to its INTERFACE).

Signed-off-by: Arjav Patel <arjav1528@gmail.com>
End-to-end exercise of the micro-ROS stack on NuttX: calls
microros_transport_init() to register the configured backend,
brings up rclc_support / node / publisher, publishes 30
std_msgs/Int32 messages on /nuttx_pub at 1 Hz, then tears the
stack down cleanly.

The example's Make.defs adds $(APPDIR)/system/microros/transport
to its own CFLAGS rather than the system/microros Make.defs, so
the transport-glue header path is not pushed into the global
search path for unrelated apps.

Serves as the smoke test for the transport layer and as a template
for downstream publisher apps.

Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants