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 2026/06/01 16:15:31 UTC

(nuttx-apps) branch master updated (fa46bdf9e -> 108122550)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


    from fa46bdf9e testing/drivers/crypto: Add SH224 hash test
     new 3d6ea0cce system/microros: Fix toolchain attribute strip breaking libc inlines.
     new 0a0118b93 system/microros: Wire libmicroros include layout and sim final link.
     new 5e91459b1 system/microros: Add UDP and serial custom transport backends.
     new 108122550 examples/microros_pub: Add minimal Int32 publisher example.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 examples/{leds => microros_pub}/CMakeLists.txt     |  20 +-
 examples/microros_pub/Kconfig                      |  30 +++
 .../lame => examples/microros_pub}/Make.defs       |   6 +-
 .../mml_parser => examples/microros_pub}/Makefile  |   9 +-
 .../microros_pub_main.c}                           |  88 +++++----
 .../rand.h => include/system/microros_transport.h  |  20 +-
 system/microros/CMakeLists.txt                     |  20 ++
 system/microros/Make.defs                          |   8 +-
 system/microros/Makefile                           |  14 +-
 system/microros/micro_ros_lib/toolchain.cmake.in   |   4 +-
 .../microros/transport/microros_transport.c        |  48 ++---
 .../microros/transport/microros_transport.h        |  63 +++---
 .../microros/transport/microros_transport_serial.c | 216 +++++++++++++++++++++
 system/microros/transport/microros_transport_udp.c | 162 ++++++++++++++++
 14 files changed, 585 insertions(+), 123 deletions(-)
 copy examples/{leds => microros_pub}/CMakeLists.txt (82%)
 create mode 100644 examples/microros_pub/Kconfig
 copy {audioutils/lame => examples/microros_pub}/Make.defs (88%)
 copy {audioutils/mml_parser => examples/microros_pub}/Makefile (79%)
 copy examples/{scd41/scd41_main.c => microros_pub/microros_pub_main.c} (50%)
 copy crypto/openssl_mbedtls_wrapper/include/openssl/rand.h => include/system/microros_transport.h (71%)
 copy netutils/libcurl4nx/curl4nx_easy_getinfo.c => system/microros/transport/microros_transport.c (60%)
 copy include/netutils/dhcp6c.h => system/microros/transport/microros_transport.h (53%)
 create mode 100644 system/microros/transport/microros_transport_serial.c
 create mode 100644 system/microros/transport/microros_transport_udp.c


(nuttx-apps) 04/04: examples/microros_pub: Add minimal Int32 publisher example.

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 1081225509857d4e265b28b242d59d314399380e
Author: Arjav Patel <ar...@gmail.com>
AuthorDate: Sun May 31 10:11:34 2026 +0530

    examples/microros_pub: Add minimal Int32 publisher example.
    
    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 <ar...@gmail.com>
---
 examples/microros_pub/CMakeLists.txt      |  35 ++++++++++
 examples/microros_pub/Kconfig             |  30 ++++++++
 examples/microros_pub/Make.defs           |  25 +++++++
 examples/microros_pub/Makefile            |  32 +++++++++
 examples/microros_pub/microros_pub_main.c | 109 ++++++++++++++++++++++++++++++
 5 files changed, 231 insertions(+)

diff --git a/examples/microros_pub/CMakeLists.txt b/examples/microros_pub/CMakeLists.txt
new file mode 100644
index 000000000..8bf83218e
--- /dev/null
+++ b/examples/microros_pub/CMakeLists.txt
@@ -0,0 +1,35 @@
+# ##############################################################################
+# apps/examples/microros_pub/CMakeLists.txt
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License.  You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# ##############################################################################
+
+if(CONFIG_EXAMPLES_MICROROS_PUB)
+  nuttx_add_application(
+    NAME
+    ${CONFIG_EXAMPLES_MICROROS_PUB_PROGNAME}
+    SRCS
+    microros_pub_main.c
+    STACKSIZE
+    ${CONFIG_EXAMPLES_MICROROS_PUB_STACKSIZE}
+    PRIORITY
+    ${CONFIG_EXAMPLES_MICROROS_PUB_PRIORITY}
+    DEPENDS
+    microros_transport)
+endif()
diff --git a/examples/microros_pub/Kconfig b/examples/microros_pub/Kconfig
new file mode 100644
index 000000000..a1d75478d
--- /dev/null
+++ b/examples/microros_pub/Kconfig
@@ -0,0 +1,30 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config EXAMPLES_MICROROS_PUB
+	tristate "micro-ROS int32 publisher example"
+	default n
+	depends on SYSTEM_MICROROS
+	---help---
+		Minimal micro-ROS publisher that creates a node and publishes
+		an std_msgs/Int32 every second on the topic /nuttx_pub.  Used
+		to validate the NuttX-native transport layer end-to-end with
+		a micro-ROS agent.
+
+if EXAMPLES_MICROROS_PUB
+
+config EXAMPLES_MICROROS_PUB_PROGNAME
+	string "Program name"
+	default "microros_pub"
+
+config EXAMPLES_MICROROS_PUB_PRIORITY
+	int "micro-ROS pub task priority"
+	default 100
+
+config EXAMPLES_MICROROS_PUB_STACKSIZE
+	int "micro-ROS pub stack size"
+	default 8192
+
+endif
diff --git a/examples/microros_pub/Make.defs b/examples/microros_pub/Make.defs
new file mode 100644
index 000000000..16128b96e
--- /dev/null
+++ b/examples/microros_pub/Make.defs
@@ -0,0 +1,25 @@
+############################################################################
+# apps/examples/microros_pub/Make.defs
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+ifneq ($(CONFIG_EXAMPLES_MICROROS_PUB),)
+CONFIGURED_APPS += $(APPDIR)/examples/microros_pub
+endif
diff --git a/examples/microros_pub/Makefile b/examples/microros_pub/Makefile
new file mode 100644
index 000000000..1377e68b5
--- /dev/null
+++ b/examples/microros_pub/Makefile
@@ -0,0 +1,32 @@
+############################################################################
+# apps/examples/microros_pub/Makefile
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+PROGNAME  = $(CONFIG_EXAMPLES_MICROROS_PUB_PROGNAME)
+PRIORITY  = $(CONFIG_EXAMPLES_MICROROS_PUB_PRIORITY)
+STACKSIZE = $(CONFIG_EXAMPLES_MICROROS_PUB_STACKSIZE)
+MODULE    = $(CONFIG_EXAMPLES_MICROROS_PUB)
+
+MAINSRC = microros_pub_main.c
+
+include $(APPDIR)/Application.mk
diff --git a/examples/microros_pub/microros_pub_main.c b/examples/microros_pub/microros_pub_main.c
new file mode 100644
index 000000000..d9211c36b
--- /dev/null
+++ b/examples/microros_pub/microros_pub_main.c
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * apps/examples/microros_pub/microros_pub_main.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rcl/rcl.h>
+#include <rcl/error_handling.h>
+#include <rclc/rclc.h>
+#include <rclc/executor.h>
+#include <std_msgs/msg/int32.h>
+
+#include <system/microros_transport.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  rcl_publisher_t       publisher;
+  std_msgs__msg__Int32  msg;
+  rcl_allocator_t       allocator;
+  rclc_support_t        support;
+  rcl_node_t            node;
+  int                   i;
+
+  printf("microros_pub: starting\n");
+
+  if (microros_transport_init() != 0)
+    {
+      printf("microros_pub: transport init failed\n");
+      return 1;
+    }
+
+  allocator = rcl_get_default_allocator();
+
+  if (rclc_support_init(&support, 0, NULL, &allocator) != RCL_RET_OK)
+    {
+      printf("microros_pub: rclc_support_init failed\n");
+      return 1;
+    }
+
+  if (rclc_node_init_default(&node, "nuttx_node", "", &support)
+      != RCL_RET_OK)
+    {
+      printf("microros_pub: node init failed\n");
+      return 1;
+    }
+
+  if (rclc_publisher_init_default(
+        &publisher,
+        &node,
+        ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
+        "nuttx_pub") != RCL_RET_OK)
+    {
+      printf("microros_pub: publisher init failed\n");
+      return 1;
+    }
+
+  msg.data = 0;
+
+  for (i = 0; i < 30; i++)
+    {
+      if (rcl_publish(&publisher, &msg, NULL) == RCL_RET_OK)
+        {
+          printf("microros_pub: sent %d\n", (int)msg.data);
+        }
+      else
+        {
+          printf("microros_pub: publish failed\n");
+        }
+
+      msg.data++;
+      sleep(1);
+    }
+
+  rcl_publisher_fini(&publisher, &node);
+  rcl_node_fini(&node);
+  rclc_support_fini(&support);
+
+  printf("microros_pub: done\n");
+  return 0;
+}


(nuttx-apps) 02/04: system/microros: Wire libmicroros include layout and sim final link.

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 0a0118b93c8f324b1716a9401b6c66a9876adc60
Author: Arjav Patel <ar...@gmail.com>
AuthorDate: Sun May 31 10:11:14 2026 +0530

    system/microros: Wire libmicroros include layout and sim final link.
    
    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 <ar...@gmail.com>
---
 system/microros/Make.defs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/system/microros/Make.defs b/system/microros/Make.defs
index ae95e997d..beb8a0c3d 100644
--- a/system/microros/Make.defs
+++ b/system/microros/Make.defs
@@ -23,8 +23,10 @@
 ifneq ($(CONFIG_SYSTEM_MICROROS),)
 CONFIGURED_APPS += $(APPDIR)/system/microros
 
-CFLAGS   += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include
-CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/system/microros/include
+MICROROS_INC_DIRS := $(APPDIR)/system/microros/include \
+                     $(wildcard $(APPDIR)/system/microros/include/*)
+CFLAGS   += $(foreach d,$(MICROROS_INC_DIRS),${INCDIR_PREFIX}$(d))
+CXXFLAGS += $(foreach d,$(MICROROS_INC_DIRS),${INCDIR_PREFIX}$(d))
 
-LDLIBS   += $(APPDIR)/system/microros/libmicroros.a
+EXTRA_LIBS += $(APPDIR)/system/microros/libmicroros.a
 endif


(nuttx-apps) 01/04: system/microros: Fix toolchain attribute strip breaking libc inlines.

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 3d6ea0ccece3a1ccd917940b16bb1ff6a5ae3f5e
Author: Arjav Patel <ar...@gmail.com>
AuthorDate: Sun May 31 10:11:06 2026 +0530

    system/microros: Fix toolchain attribute strip breaking libc inlines.
    
    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 <ar...@gmail.com>
---
 system/microros/micro_ros_lib/toolchain.cmake.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/system/microros/micro_ros_lib/toolchain.cmake.in b/system/microros/micro_ros_lib/toolchain.cmake.in
index 8d3aabe3c..ebfa15eea 100644
--- a/system/microros/micro_ros_lib/toolchain.cmake.in
+++ b/system/microros/micro_ros_lib/toolchain.cmake.in
@@ -9,8 +9,8 @@ set(PLATFORM_NAME "nuttx")
 set(CMAKE_C_COMPILER @CMAKE_C_COMPILER@)
 set(CMAKE_CXX_COMPILER @CMAKE_CXX_COMPILER@)
 
-set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE)
-set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D__NuttX__ -D'__attribute__(x)='" CACHE STRING "" FORCE)
+set(CMAKE_C_FLAGS_INIT "-std=c11 @ARCH_C_FLAGS@ -D__NuttX__" CACHE STRING "" FORCE)
+set(CMAKE_CXX_FLAGS_INIT "-std=c++14 @ARCH_CPP_FLAGS@ -fno-rtti -D__NuttX__" CACHE STRING "" FORCE)
 
 set(NUTTX_TOPDIR @NUTTX_TOPDIR@)
 set(NUTTX_APPDIR @NUTTX_APPDIR@)


(nuttx-apps) 03/04: system/microros: Add UDP and serial custom transport backends.

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 5e91459b1a16f0ab4dd14fc66ee4c35ec3b9af12
Author: Arjav Patel <ar...@gmail.com>
AuthorDate: Sun May 31 10:11:25 2026 +0530

    system/microros: Add UDP and serial custom transport backends.
    
    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 <ar...@gmail.com>
---
 include/system/microros_transport.h                |  50 +++++
 system/microros/CMakeLists.txt                     |  20 ++
 system/microros/Makefile                           |  14 +-
 system/microros/transport/microros_transport.c     |  62 ++++++
 system/microros/transport/microros_transport.h     |  67 +++++++
 .../microros/transport/microros_transport_serial.c | 216 +++++++++++++++++++++
 system/microros/transport/microros_transport_udp.c | 162 ++++++++++++++++
 7 files changed, 590 insertions(+), 1 deletion(-)

diff --git a/include/system/microros_transport.h b/include/system/microros_transport.h
new file mode 100644
index 000000000..fc89bde3c
--- /dev/null
+++ b/include/system/microros_transport.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * apps/include/system/microros_transport.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_INCLUDE_SYSTEM_MICROROS_TRANSPORT_H
+#define __APPS_INCLUDE_SYSTEM_MICROROS_TRANSPORT_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/* microros_transport_init
+ *
+ * Register the NuttX-native transport (UDP or Serial, selected by Kconfig)
+ * with the rmw_microxrcedds layer.  Must be called once before
+ * rclc_support_init().
+ *
+ * Returns 0 on success, negated errno on failure.
+ */
+
+int microros_transport_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPS_INCLUDE_SYSTEM_MICROROS_TRANSPORT_H */
diff --git a/system/microros/CMakeLists.txt b/system/microros/CMakeLists.txt
index 44cd0d25b..1c3d89576 100644
--- a/system/microros/CMakeLists.txt
+++ b/system/microros/CMakeLists.txt
@@ -44,4 +44,24 @@ if(CONFIG_SYSTEM_MICROROS)
     microros PROPERTIES IMPORTED_LOCATION ${MICROROS_DIR}/libmicroros.a
                         INTERFACE_INCLUDE_DIRECTORIES ${MICROROS_DIR}/include)
   add_dependencies(microros microros_build)
+
+  # Transport glue compiled into the apps tree
+  set(MICROROS_TRANSPORT_SRCS ${MICROROS_DIR}/transport/microros_transport.c)
+
+  if(CONFIG_MICROROS_TRANSPORT_UDP)
+    list(APPEND MICROROS_TRANSPORT_SRCS
+         ${MICROROS_DIR}/transport/microros_transport_udp.c)
+  endif()
+
+  if(CONFIG_MICROROS_TRANSPORT_SERIAL)
+    list(APPEND MICROROS_TRANSPORT_SRCS
+         ${MICROROS_DIR}/transport/microros_transport_serial.c)
+  endif()
+
+  nuttx_add_library(microros_transport STATIC)
+  target_sources(microros_transport PRIVATE ${MICROROS_TRANSPORT_SRCS})
+  target_include_directories(microros_transport
+                             PRIVATE ${MICROROS_DIR}/transport)
+  target_include_directories(microros_transport PUBLIC ${MICROROS_DIR}/include)
+  add_dependencies(microros_transport microros_build)
 endif()
diff --git a/system/microros/Makefile b/system/microros/Makefile
index 6d34e3cc3..18067408f 100644
--- a/system/microros/Makefile
+++ b/system/microros/Makefile
@@ -25,7 +25,7 @@ include $(APPDIR)/Make.defs
 MICROROS_DIR     := $(APPDIR)/system/microros
 MICROROS_LIB_DIR := $(MICROROS_DIR)/micro_ros_lib
 MICROROS_DISTRO  := $(patsubst "%",%,$(CONFIG_MICROROS_DISTRO))
-MICROROS_AR      := $(CROSSDEV)ar
+MICROROS_AR      := $(firstword $(AR))
 
 MAX_NODES   := $(CONFIG_MICROROS_MAX_NODES)
 MAX_PUB     := $(CONFIG_MICROROS_MAX_PUBLISHERS)
@@ -44,6 +44,18 @@ ESCAPED_CXXFLAGS := $(subst /,\/,$(subst ",,$(CXXFLAGS)))
 
 MENUDESC = "micro-ROS Library"
 
+# Transport sources compiled into the user-side app library
+
+CSRCS += transport/microros_transport.c
+
+ifeq ($(CONFIG_MICROROS_TRANSPORT_UDP),y)
+CSRCS += transport/microros_transport_udp.c
+endif
+
+ifeq ($(CONFIG_MICROROS_TRANSPORT_SERIAL),y)
+CSRCS += transport/microros_transport_serial.c
+endif
+
 # Architecture for CMake toolchain
 ifeq ($(CONFIG_ARCH_ARM),y)
 MICROROS_ARCH := arm
diff --git a/system/microros/transport/microros_transport.c b/system/microros/transport/microros_transport.c
new file mode 100644
index 000000000..e9fdc44fa
--- /dev/null
+++ b/system/microros/transport/microros_transport.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * apps/system/microros/transport/microros_transport.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <errno.h>
+
+#include <rmw_microros/rmw_microros.h>
+
+#include <system/microros_transport.h>
+
+#include "microros_transport.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int microros_transport_init(void)
+{
+#if defined(CONFIG_MICROROS_TRANSPORT_UDP)
+  rmw_uros_set_custom_transport(false,
+                                NULL,
+                                microros_udp_open,
+                                microros_udp_close,
+                                microros_udp_write,
+                                microros_udp_read);
+  return 0;
+#elif defined(CONFIG_MICROROS_TRANSPORT_SERIAL)
+  rmw_uros_set_custom_transport(true,
+                                NULL,
+                                microros_serial_open,
+                                microros_serial_close,
+                                microros_serial_write,
+                                microros_serial_read);
+  return 0;
+#else
+  return -ENOSYS;
+#endif
+}
diff --git a/system/microros/transport/microros_transport.h b/system/microros/transport/microros_transport.h
new file mode 100644
index 000000000..4483b8ffc
--- /dev/null
+++ b/system/microros/transport/microros_transport.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * apps/system/microros/transport/microros_transport.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_SYSTEM_MICROROS_TRANSPORT_MICROROS_TRANSPORT_H
+#define __APPS_SYSTEM_MICROROS_TRANSPORT_MICROROS_TRANSPORT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <uxr/client/profile/transport/custom/custom_transport.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/* Backend callbacks.  Exposed for testing only. */
+
+bool   microros_udp_open(struct uxrCustomTransport *transport);
+bool   microros_udp_close(struct uxrCustomTransport *transport);
+size_t microros_udp_write(struct uxrCustomTransport *transport,
+                          const uint8_t *buf, size_t len, uint8_t *err);
+size_t microros_udp_read(struct uxrCustomTransport *transport,
+                         uint8_t *buf, size_t len,
+                         int timeout_ms, uint8_t *err);
+
+bool   microros_serial_open(struct uxrCustomTransport *transport);
+bool   microros_serial_close(struct uxrCustomTransport *transport);
+size_t microros_serial_write(struct uxrCustomTransport *transport,
+                             const uint8_t *buf, size_t len, uint8_t *err);
+size_t microros_serial_read(struct uxrCustomTransport *transport,
+                            uint8_t *buf, size_t len,
+                            int timeout_ms, uint8_t *err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPS_SYSTEM_MICROROS_TRANSPORT_MICROROS_TRANSPORT_H */
diff --git a/system/microros/transport/microros_transport_serial.c b/system/microros/transport/microros_transport_serial.c
new file mode 100644
index 000000000..6a9c7badc
--- /dev/null
+++ b/system/microros/transport/microros_transport_serial.c
@@ -0,0 +1,216 @@
+/****************************************************************************
+ * apps/system/microros/transport/microros_transport_serial.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <fcntl.h>
+#include <poll.h>
+#include <stdint.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "microros_transport.h"
+
+/****************************************************************************
+ * Private Helpers
+ ****************************************************************************/
+
+static inline int serial_fd(struct uxrCustomTransport *transport)
+{
+  return (int)(intptr_t)transport->args - 1;
+}
+
+static inline void serial_set_fd(struct uxrCustomTransport *transport,
+                                 int fd)
+{
+  transport->args = (void *)(intptr_t)(fd + 1);
+}
+
+static int set_baud(struct termios *tio, int baud)
+{
+  speed_t s;
+
+  switch (baud)
+    {
+      case 9600:
+        s = B9600;
+        break;
+
+      case 19200:
+        s = B19200;
+        break;
+
+      case 38400:
+        s = B38400;
+        break;
+
+      case 57600:
+        s = B57600;
+        break;
+
+      case 115200:
+        s = B115200;
+        break;
+
+      case 230400:
+        s = B230400;
+        break;
+
+      case 460800:
+        s = B460800;
+        break;
+
+      case 921600:
+        s = B921600;
+        break;
+
+      default:
+        return -1;
+    }
+
+  cfsetispeed(tio, s);
+  cfsetospeed(tio, s);
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool microros_serial_open(struct uxrCustomTransport *transport)
+{
+  struct termios tio;
+  int fd;
+
+  fd = open(CONFIG_MICROROS_SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_CLOEXEC);
+  if (fd < 0)
+    {
+      return false;
+    }
+
+  if (tcgetattr(fd, &tio) < 0)
+    {
+      close(fd);
+      return false;
+    }
+
+  cfmakeraw(&tio);
+  tio.c_cflag |= (CLOCAL | CREAD);
+  tio.c_cflag &= ~CRTSCTS;
+  tio.c_cc[VMIN]  = 0;
+  tio.c_cc[VTIME] = 0;
+
+  if (set_baud(&tio, CONFIG_MICROROS_SERIAL_BAUD) < 0)
+    {
+      close(fd);
+      return false;
+    }
+
+  if (tcsetattr(fd, TCSANOW, &tio) < 0)
+    {
+      close(fd);
+      return false;
+    }
+
+  tcflush(fd, TCIOFLUSH);
+  serial_set_fd(transport, fd);
+  return true;
+}
+
+bool microros_serial_close(struct uxrCustomTransport *transport)
+{
+  int fd = serial_fd(transport);
+
+  if (fd >= 0)
+    {
+      close(fd);
+      serial_set_fd(transport, -1);
+    }
+
+  return true;
+}
+
+size_t microros_serial_write(struct uxrCustomTransport *transport,
+                             const uint8_t *buf, size_t len, uint8_t *err)
+{
+  int fd = serial_fd(transport);
+  ssize_t n;
+
+  if (fd < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  n = write(fd, buf, len);
+  if (n < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  return n;
+}
+
+size_t microros_serial_read(struct uxrCustomTransport *transport,
+                            uint8_t *buf, size_t len,
+                            int timeout_ms, uint8_t *err)
+{
+  int fd = serial_fd(transport);
+  struct pollfd pfd;
+  ssize_t n;
+  int r;
+
+  if (fd < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  pfd.fd     = fd;
+  pfd.events = POLLIN;
+
+  r = poll(&pfd, 1, timeout_ms);
+  if (r < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  if (r == 0)
+    {
+      return 0;
+    }
+
+  n = read(fd, buf, len);
+  if (n < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  return n;
+}
diff --git a/system/microros/transport/microros_transport_udp.c b/system/microros/transport/microros_transport_udp.c
new file mode 100644
index 000000000..6b048a480
--- /dev/null
+++ b/system/microros/transport/microros_transport_udp.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * apps/system/microros/transport/microros_transport_udp.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "microros_transport.h"
+
+/****************************************************************************
+ * Private Helpers
+ ****************************************************************************/
+
+static inline int udp_fd(struct uxrCustomTransport *transport)
+{
+  return (int)(intptr_t)transport->args - 1;
+}
+
+static inline void udp_set_fd(struct uxrCustomTransport *transport, int fd)
+{
+  transport->args = (void *)(intptr_t)(fd + 1);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool microros_udp_open(struct uxrCustomTransport *transport)
+{
+  struct sockaddr_in addr;
+  int fd;
+
+  fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+  if (fd < 0)
+    {
+      return false;
+    }
+
+  memset(&addr, 0, sizeof(addr));
+  addr.sin_family = AF_INET;
+  addr.sin_port   = htons(CONFIG_MICROROS_AGENT_PORT);
+
+  if (inet_pton(AF_INET, CONFIG_MICROROS_AGENT_IP, &addr.sin_addr) != 1)
+    {
+      close(fd);
+      return false;
+    }
+
+  if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+    {
+      close(fd);
+      return false;
+    }
+
+  udp_set_fd(transport, fd);
+  return true;
+}
+
+bool microros_udp_close(struct uxrCustomTransport *transport)
+{
+  int fd = udp_fd(transport);
+
+  if (fd >= 0)
+    {
+      close(fd);
+      udp_set_fd(transport, -1);
+    }
+
+  return true;
+}
+
+size_t microros_udp_write(struct uxrCustomTransport *transport,
+                          const uint8_t *buf, size_t len, uint8_t *err)
+{
+  int fd = udp_fd(transport);
+  ssize_t n;
+
+  if (fd < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  n = send(fd, buf, len, 0);
+  if (n < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  return n;
+}
+
+size_t microros_udp_read(struct uxrCustomTransport *transport,
+                         uint8_t *buf, size_t len,
+                         int timeout_ms, uint8_t *err)
+{
+  int fd = udp_fd(transport);
+  struct pollfd pfd;
+  ssize_t n;
+  int r;
+
+  if (fd < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  pfd.fd     = fd;
+  pfd.events = POLLIN;
+
+  r = poll(&pfd, 1, timeout_ms);
+  if (r < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  if (r == 0)
+    {
+      return 0;
+    }
+
+  n = recv(fd, buf, len, 0);
+  if (n < 0)
+    {
+      *err = 1;
+      return 0;
+    }
+
+  return n;
+}