Skip to main content

Module custom_transport

Module custom_transport 

Source
Expand description

Phase 115.A — runtime-pluggable custom transport vtable.

Defines the platform-side hook that lets users plug a custom transport (USB-CDC, BLE, RS-485, semihosting bridge, ring-buffer loopback) at runtime without changing board crate, Cargo features, or rebuilding.

The shape mirrors micro-ROS’s rmw_uros_set_custom_transport(framing, params, open, close, write, read) and the C ABI exposed by nros-c / nros-cpp as nros_transport_ops_t.

§Why a fn-pointer vtable, not a Rust trait

  1. alloc-free. A Box<dyn CustomTransport> would force the alloc crate on every no_std backend that wants to use the runtime hook. nano-ros’s bare-metal / FreeRTOS / NuttX / ThreadX targets ship without a global allocator on the default feature flags, so dyn is a non-starter.
  2. C ABI parity. The user-facing surface is nros_transport_ops_t (a #[repr(C)] struct of fn pointers + a void *). A Rust-side fn-ptr vtable means the set_custom_transport C entry just memcpys the incoming struct into the static — no glue, no shims, no trampolines.
  3. Matches XRCE’s existing shape. uxr_set_custom_transport_callbacks already takes 4 raw fn pointers; the Rust wrapper at nros-rmw-xrce::init_transport likewise. A trait would just be an extra layer that has to be type-erased into fn pointers anyway.

See docs/roadmap/phase-115-runtime-transport-vtable.md § A.1 for the full discussion.

§Threading contract (v1)

  • read and write may NOT be called concurrently from different threads. The active backend serialises them through the drive_io / spin-once path. Custom transports written against this contract can use a single-buffer state machine without internal locking.
  • Callbacks must NOT be invoked from interrupt context. Wrap ISR-driven hardware in a queue + read poller.
  • user_data is opaque to the runtime — its Send / Sync discipline is the caller’s responsibility. The vtable struct itself is Send + Sync because the four fn pointers always are.

Structs§

NrosTransportOps
Phase 115.A — runtime-pluggable custom transport. Caller fills in the four fn pointers, hands the struct to set_custom_transport, and the active backend treats it as the read / write surface for every wire frame.

Constants§

NROS_TRANSPORT_OPS_ABI_VERSION_V1
Phase 115.A.2 — current ABI version of NrosTransportOps.

Functions§

peek_custom_transport
Phase 115.A — peek at the currently-registered transport without consuming it. Used by backends that need to re-attach on session reconnect, or by tests that want to verify a registration landed. Returns None if nothing was registered.
set_custom_transport
Phase 115.A — register a custom transport vtable. Must be called before the first Rmw::open (or nros_support_init from the C surface). v1 leaves enforcement of “before init” to backend code — they reject re-registration with NROS_RMW_RET_ALREADY_INIT after Rmw::open succeeds.
take_custom_transport
Phase 115.A — drain the registered transport. Returns the previously-registered vtable (None if nothing was registered) and clears the slot. Backends call this from Rmw::open when platform-custom is the active platform; the vtable then lives inside the session for the rest of the process lifetime.