---
title: "How Does Rosette Put an RP2350 + W5100S Board on a ROS 2 Network Without a micro-ROS Agent?"
url: "https://maker.wiznet.io/Grace_Koo/projects/how-does-rosette-put-an-rp2350-w5100s-board-on-a-ros-2-network-without-a-micro-ros-agent/"
markdown_url: "https://maker.wiznet.io/Grace_Koo/projects/how-does-rosette-put-an-rp2350-w5100s-board-on-a-ros-2-network-without-a-micro-ros-agent/md"
type: "UCC: User Created Content"
author: "CenteredSolutions"
author_url: "https://github.com/CenteredSolutions/Rosette"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "CenteredSolutions"
original_url: "https://github.com/CenteredSolutions/Rosette"
license: "Apache License 2.0 (Apache-2.0)"
published: "2026-11-09"
language: "en"
tags: ["w5100s", "rp2350", "ROS2", "RTPS", "Hardware UDP"]
hardware: ["WIZnet W5100S-EVB-Pico2"]
likes: 0
views: 10
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# How Does Rosette Put an RP2350 + W5100S Board on a ROS 2 Network Without a micro-ROS Agent?

> Rosette runs a DDSI-RTPS stack and rmw_rosette on bare-metal RP2350, using W5100S hardware UDP sockets so stock Fast DDS sees the board as a ROS 2 node.

Original author: CenteredSolutions (source: https://github.com/CenteredSolutions/Rosette)

## Components

- **WIZnet W5100S-EVB-Pico2** x 1 ([docs](https://wiznet.io/products/powered-by-raspberry-pi/w5100s-evb-pico2))

## Documents and links

- [Rosette source (RTPS stack, rmw_rosette, WIZnet driver)](https://github.com/CenteredSolutions/Rosette) (code)

## Article

> 📚 **Context**: [CenteredSolutions/Rosette](https://github.com/CenteredSolutions/Rosette) — a DDSI-RTPS 2.5 stack and rmw implementation for microcontrollers. A stock rclc program on a WIZnet EVB board joins a ROS 2 network directly, next to Fast DDS and Cyclone DDS nodes.

---

## 01 — What changes without the agent

![micro-ROS sends XRCE-DDS to an agent on a host PC; Rosette runs rclc, rmw_rosette and rosette::rtps on the board and speaks RTPS over W5100S hardware UDP straight to ROS 2 nodes](https://maker.wiznet.io/upload/ckeditor5/c138942837874c60b3b940f9d9430dcd.jpg)

*micro-ROS sends XRCE-DDS to an agent on a host PC; Rosette runs rclc, rmw_rosette and rosette::rtps on the board and speaks RTPS over W5100S hardware UDP straight to ROS 2 nodes*

With micro-ROS, the agent on a host joins DDS for the board. Rosette puts RTPS on the board itself. The firmware is an unmodified rclc program linked against `rmw_rosette`. Stock rcl and rclc are still built with micro_ros_setup's `generate_lib`, but `rmw_microxrcedds` is never linked.

| Proven (README) | Where |
| --- | --- |
| Topics and services both ways with stock rmw_fastrtps_cpp (Humble) | interop harness |
| ros2 node list / node info show Rosette nodes | same harness |
| rclc on RP2350 + W5100S, no RTOS, rcl heap steady at about 4 KB | W5100S-EVB-Pico2 |
| 64 KB messages through a link that drops datagrams over 1472 B | fragmentation harness |
| DHCP, IPv6 link-local and SLAAC, UDP echo | W6100-EVB-Pico |

---

## 02 — The chip and the boards

Rosette does not use ioLibrary. It has its own header-only driver, `WiznetDevice<Chip, Bus>` in `ports/net/wiznet/`, and on a board the network is the chip's hardware UDP. The board CMake states the result: no RTOS, a cooperative superloop.

| Item | W5100S-EVB-Pico2 |
| --- | --- |
| Bus | SPI0, mode 0, 31.25 MHz, blocking |
| Interrupt | INT on GPIO21; 2 ms polling without it |
| MAC | 00:08:DC + 3 bytes of the RP2350 unique ID |
| Address | DHCP (hostname option); link-local after 15 s, retry every 60 s |

| Board | State |
| --- | --- |
| w5100s-evb-pico2 (RP2350) | ROS examples run against stock ROS 2; default board on every host except macOS |
| w6100-evb-pico (RP2040) | dual-stack UDP echo runs; ROS examples build |
| w6100-evb-pico2, w6300-evb-pico2, w5100s-evb-pico | build |

---

## 03 — Four sockets, three for RTPS

![W5100S socket map: user data unicast 4 KiB, metatraffic unicast 2 KiB, SPDP multicast 1 KiB, DHCP/SNTP 1 KiB held only per exchange](https://maker.wiznet.io/upload/ckeditor5/3c20ec94d1d04146b52188aa9ddf9601.jpg)

*W5100S socket map: user data unicast 4 KiB, metatraffic unicast 2 KiB, SPDP multicast 1 KiB, DHCP/SNTP 1 KiB held only per exchange*

- RTPS holds three sockets for the life of the participant. **DHCP and SNTP borrow the fourth only during an exchange**; the DHCP client's header notes this "matters on a chip with four hardware sockets".

- RX memory is tilted toward user data. A socket that needs more calls `set_receive_buffer_size()` before `bind()`.

- When a full 4096-byte sample outgrows the 4 KiB buffer, the reader recovers the lost fragments with NACK_FRAG one heartbeat later.

---

## 04 — Multicast and ARP on the chip

The SPDP group socket is configured in `device.hpp` before it is opened:

```plaintext
write(Chip::socket_dest_hardware(socket), group_mac.data(), group_mac.size());
write(Chip::socket_dest_ip(socket), group.data(), group.size());
write_u16(Chip::socket_dest_port(socket), group_port);
write_u8(Chip::socket_mode(socket),
         static_cast<uint8_t>(Chip::mode_udp() |
                              Chip::mode_multicast() |
                              Chip::mode_igmp_v2()));
```

| Chip behaviour | How Rosette handles it |
| --- | --- |
| Multicast membership is latched at OPEN | join the group before bind() |
| A multicast address has no ARP answer | W5100S: SEND_MAC with the group MAC in Sn_DHAR. W6100/W6300: Sn_MR2 manual destination MAC |
| Inline ARP to a silent peer stalls a send for about 1.8 s | own ARP cache, MAC handed to each send, unknown hops resolved in the background |
| Same Sn_DIPR on reopen skips ARP and reuses an old MAC | Sn_DIPR cleared on reopen |
| Some Wi-Fi APs and managed switches drop multicast | the network notes call a wired switch "the reliable setup" |

---

## 05 — 1472 bytes, no IP reassembly

![A stock writer packs repairs into one oversized datagram that the chip drops on every retry; a Rosette reader asks for one change per ACKNACK so each repair fits](https://maker.wiznet.io/upload/ckeditor5/e64bbbf47f274475a34befd4e9aa741a.jpg)

*A stock writer packs repairs into one oversized datagram that the chip drops on every retry; a Rosette reader asks for one change per ACKNACK so each repair fits*

| Direction | Handling |
| --- | --- |
| Board → peers | samples split into DATA_FRAG at 1472 B (IPv4) or 1452 B (IPv6) |
| Repairs to the board | one missing change per ACKNACK, so each repair is a single DATA |
| Large samples from stock peers | cap Fast DDS maxMessageSize on the peer |

`RMW_ROSETTE_STRICT_LINK=1` makes a host drop every datagram over the limit, so the host tests face the board's losses against real stock traffic.

---

## 06 — No heap, measured footprint

The RTPS core and `rmw_rosette` never call `malloc` or `new`; every pool is sized at build time, so running out of room shows up at boot, not after a week in the field.

| W5100S-EVB-Pico2, RP2350, -O3 | Flash | Static RAM |
| --- | --- | --- |
| rtps_chatter (RTPS core) | 204,488 B | 62,836 B |
| rclc_chatter, default capacity | 285,236 B | 99,816 B |
| rclc_chatter, sized to what it creates | 279,108 B | 63,980 B |

| Scale (design note) | Value |
| --- | --- |
| Target network | 70–90 participants: dozens of controller boards plus camera, perception and control nodes |
| Peer table | 96 known peers at 68 B, full state for 8 active |
| Cost on an RP2040 | about 0.3 ms per datagram over SPI, 0.4–1.8 ms per SEDP sample |

Tests back this up: 152 DDSI-RTPS 2.5 statements in traceability matrices, the WIZnet driver run against a register model of the chip, and CI on Humble and Jazzy against Fast DDS and Cyclone DDS.

---

## 07 — Where it stands

- Hardware runs so far: the W5100S-EVB-Pico2 (ROS) and the W6100-EVB-Pico (UDP echo). Discovery multicast on the W6100/W6300 is confirmed when a ROS example first runs there.

- rclcpp nodes talk to Rosette nodes, but cannot load `rmw_rosette` themselves.

- Firmware samples up to 4096 B by default; IPv4 locators only; no DDS-Security; pre-1.0.

**On one wired switch, each controller board becomes a ROS 2 node in its own right, with no PC translating for it.**

---

## 08 — Similar Projects on WIZnet Makers

- [**How to Bridge Physical I/O into ROS 2 with W6100 on RP2040?**](https://maker.wiznet.io/viktor/projects/w6100-evb-pico--zephyr-micro-ros-universal-bridge/) — one of Rosette's boards on the agent route: Zephyr and micro-ROS to an agent on the host.

- [**mros2-esp32-eth1**](https://maker.wiznet.io/TheoIm/projects/mros2-esp32-eth1/) — the same no-agent goal on an ESP32-S3, with embeddedRTPS over lwIP and the W5500 as the interface. Rosette hands UDP to the chip instead.

- [**robo-con-for-Ethernet**](https://maker.wiznet.io/lawrence/projects/robo-con-for-ethernet-w5500-toe-for-ros-2-connected-robot-control/) — a WIZnet board reaching ROS 2 through a command bridge.

---

## Q&A

**Q. In what mode is the WIZnet chip used?**

Hardware UDP sockets through Rosette's own register driver. No lwIP, no RTOS; RTPS runs on the RP2350 on top.

**Q. Does it need a micro-ROS agent?**

No. An optional agent backend exists for setups that want one.

**Q. Can it be reused?**

Apache-2.0. The bundled Pico SDK board headers are BSD-3-Clause.

---

**Original Link**: https://github.com/CenteredSolutions/Rosette

**WIZnet driver**: `ports/net/wiznet/device.hpp` · **RTPS sockets**: `src/rtps/transport.cpp` · **Memory**: `docs/mcu_memory_model.md` · **Network**: `docs/network_configuration.md`

---

Source: https://maker.wiznet.io/Grace_Koo/projects/how-does-rosette-put-an-rp2350-w5100s-board-on-a-ros-2-network-without-a-micro-ros-agent/
