pub trait NodeDispatchRuntime {
// Required method
fn spin_once(&mut self, timeout_ms: u32) -> Result<(), ()>;
// Provided methods
fn apply_lifecycle(&mut self, autostart: u8) -> Result<(), &'static str> { ... }
fn apply_param_services(&mut self) -> Result<(), &'static str> { ... }
fn apply_param_store(&mut self) -> Result<(), &'static str> { ... }
fn executor_handle(&mut self) -> *mut c_void { ... }
fn apply_declared_params(
&mut self,
nodes: &'static [(&'static str, &'static str)],
params: &'static [(&'static str, &'static str, u8)],
) -> Result<(), &'static str> { ... }
fn observed_callback_counts(&self) -> (usize, usize) { ... }
fn signal_callback(&mut self, _cb: SignaledCallback<'_>) { ... }
fn dispatch_strategy(&self) -> DispatchStrategy { ... }
}Expand description
Node runtime sink the codegen-emitted run_plan(runtime)
body talks to (Phase 212.N.7 step-3.1).
Object-safe + no_std. The concrete impl
(ExecutorNodeRuntime in nros) owns the live executor;
BoardEntry::run installs it on the per-boot
RuntimeCtx::runtime slot before invoking the user setup
closure.
Phase 214.K.1 — renamed from NodeRuntime to disambiguate from
the user-facing nros::NodeRuntime metadata-sink trait in
packages/api/nros/src/node.rs:112. The two traits live at
different layers (board-side dispatch sink vs user-side metadata
declaration sink) and the previous shared name forced explicit
nros_platform:: / nros:: qualification at every use site +
produced confusing impl NodeRuntime for X ambiguity. The
phase-214.K.1 NodeRuntime deprecation alias was removed in phase-313
W1 (issue #0243); use NodeDispatchRuntime directly.
Required Methods§
Sourcefn spin_once(&mut self, timeout_ms: u32) -> Result<(), ()>
fn spin_once(&mut self, timeout_ms: u32) -> Result<(), ()>
Drive the underlying executor for at most timeout_ms
milliseconds. Ok(()) on a clean spin (including timeout);
Err(()) if the executor surfaces a spin error.
Result<_, ()> is deliberate: the board entry-point callers
(nros-board-{freertos,nuttx,threadx} spin loops) only
{:?}-print the error and B::exit_failure() — a typed enum
would carry no extra info across the trait boundary, since the
underlying ExecutorError from nros::node_runtime is mapped
to () at the impl site (impl NodeDispatchRuntime for ExecutorNodeRuntime). #[allow] keeps the surface narrow.
Provided Methods§
Sourcefn apply_lifecycle(&mut self, autostart: u8) -> Result<(), &'static str>
fn apply_lifecycle(&mut self, autostart: u8) -> Result<(), &'static str>
Phase 264 W2 — register the REP-2002 lifecycle services on the underlying
executor + drive boot autostart. autostart: 0 = none, 1 = configure,
2 = configure+activate. Default no-op (non-executor runtimes, or nros
built without lifecycle-services); the ExecutorNodeRuntime impl in
nros does the real work behind that feature. nros::main! calls this
(via RuntimeCtx::apply_lifecycle) when system.toml declares
[lifecycle], mirroring the bake’s generate.rs::render_lifecycle_fn.
issue 0460 — the Err carries a STATIC REASON, not ().
A capability that fails to register is reported by the caller as
RuntimeError::NodeRegister("lifecycle"), which names WHICH capability
and nothing about WHY. On Zephyr that opaque string was the entire
diagnostic for three dead entries: the image printed nothing after
“Network ready” and the cause could only be guessed at. &'static str
rather than a typed error because this trait lives below nros-node and
cannot name NodeError.
Sourcefn apply_param_services(&mut self) -> Result<(), &'static str>
fn apply_param_services(&mut self) -> Result<(), &'static str>
Phase 264 W4b – register the 6 ROS 2 parameter services on the underlying
executor and create its volatile RAM param store. Launch <param>
initials are NOT passed here (issue 1272): each node’s are seeded on that
node as it is built, from the params slice nros::main! sets before
the node’s register call. After this,
ros2 param list/get/set works against the running node; reconfigured values
live in RAM until the next boot (RFC-0004 §10; persistence is out of scope,
issue 0080). Default no-op (non-executor runtimes, or nros built without
param-services); the ExecutorNodeRuntime impl in nros does the real work
behind that feature. nros::main! calls this (via
RuntimeCtx::apply_param_services) when system.toml declares
[param_services], mirroring the bake’s generate.rs::render_param_persistence_fn.
issue 0460 — the Err carries a STATIC REASON, not ().
A capability that fails to register is reported by the caller as
RuntimeError::NodeRegister("lifecycle"), which names WHICH capability
and nothing about WHY. On Zephyr that opaque string was the entire
diagnostic for three dead entries: the image printed nothing after
“Network ready” and the cause could only be guessed at. &'static str
rather than a typed error because this trait lives below nros-node and
cannot name NodeError.
Sourcefn apply_param_store(&mut self) -> Result<(), &'static str>
fn apply_param_store(&mut self) -> Result<(), &'static str>
phase-461 W6 – build the parameter STORE and register no service: the
params capability axis. nros::main! calls this (via
RuntimeCtx::apply_param_store) before the per-node register calls
when the system declares params and not param_services. Default
no-op (non-executor runtimes, or nros built without param-store,
which the entry const-asserts against).
Sourcefn executor_handle(&mut self) -> *mut c_void
fn executor_handle(&mut self) -> *mut c_void
Phase 258 (Track 2, 2a) — raw *mut Executor (as void*) for the
owned-spin entry, so a Node pkg’s register(runtime) wrapper can call
the uniform __nros_component_<pkg>_install(.., executor, ..) seam
(nros::install_node_typed) instead of the retired opaque-fn-ptr
register_dispatch_slot_dyn bridge. A pointer crosses the
nros-platform → nros layering wall cleanly (the concrete
ExecutorNodeRuntime lives in nros; this trait can’t name it).
Default null — sinks without a live executor (e.g.
NullNodeRuntime, framework-dispatch-only runtimes) report no
handle; the install path treats null as a registration error.
Sourcefn apply_declared_params(
&mut self,
nodes: &'static [(&'static str, &'static str)],
params: &'static [(&'static str, &'static str, u8)],
) -> Result<(), &'static str>
fn apply_declared_params( &mut self, nodes: &'static [(&'static str, &'static str)], params: &'static [(&'static str, &'static str, u8)], ) -> Result<(), &'static str>
phase-446 W6 – hand the executor the parameters each node’s contract DECLARES, so a node whose code declares a parameter its contract does not (or with another type) refuses the boot naming the node, the parameter and the contract.
nodes is (node FQN, contract); params is (node FQN, name, rcl_interfaces type code). Plain tuples because this trait lives below
nros-params and cannot name its types. nros::main! calls this before
any node registers. Default no-op: a runtime with no parameter store
has nothing to check.
Sourcefn observed_callback_counts(&self) -> (usize, usize)
fn observed_callback_counts(&self) -> (usize, usize)
Observability counters from hosted/runtime tests.
Returns (all_callbacks, message_callbacks). Implementations
that cannot observe callback dispatch keep the default zeros.
Sourcefn signal_callback(&mut self, _cb: SignaledCallback<'_>)
fn signal_callback(&mut self, _cb: SignaledCallback<'_>)
Hand a signaled callback to the framework-side dispatcher
(Phase 216.A.2). Only meaningful for DispatchStrategy::Deferred
(RTIC / Embassy) runtimes — Inline runtimes drive callbacks
directly from spin_once and never call this. The default panic
surfaces the mis-wire loudly rather than silently dropping the
callback signal.
Sourcefn dispatch_strategy(&self) -> DispatchStrategy
fn dispatch_strategy(&self) -> DispatchStrategy
Declare how this runtime delivers callbacks (Phase 216.A.2).
nros check (Phase 216.D.1) cross-validates each Node pkg’s
Node::DISPATCH against this value. Defaults to Inline so
every existing impl reports the historical behavior unchanged.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".