Skip to main content

NodeDispatchRuntime

Trait NodeDispatchRuntime 

Source
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,
        params: &[(&str, &str)],
    ) -> Result<(), &'static str> { ... }
    fn executor_handle(&mut self) -> *mut c_void { ... }
    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§

Source

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§

Source

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.

Source

fn apply_param_services( &mut self, params: &[(&str, &str)], ) -> Result<(), &'static str>

Phase 264 W4b — register the 6 ROS 2 parameter services on the underlying executor + seed a volatile RAM param store with the launch-baked <param> initials (params is the aggregate (name, value) slice, value as the raw launch string — the impl infers the ParameterValue type). 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.

Source

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-platformnros 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.

Source

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.

Source

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.

Source

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".

Implementors§