pub struct ExecutorNodeRuntime { /* private fields */ }Expand description
Executor-backed component runtime.
Owns the Executor and one slot per registered component. The
register / spin lifecycle:
from_executorwraps an openExecutor.register_nodebuilds the component’sState, runs [Node::register] over an internalNodeRuntimeadapter that materialises nodes / pubs / subs / timers on the real executor, and wires each subscription + timer callback to dispatch intoExecutableNode::on_callbackwith the rightCallbackId.spin/spin_oncedrive the executor; between iterations every registered component’sExecutableNode::tickruns.
Implementations§
Source§impl ExecutorNodeRuntime
impl ExecutorNodeRuntime
Sourcepub fn from_executor(executor: Executor) -> Self
pub fn from_executor(executor: Executor) -> Self
Wrap an already-built Executor.
Sourcepub fn executor_mut(&mut self) -> &mut Executor
pub fn executor_mut(&mut self) -> &mut Executor
Mutably borrow the underlying executor — for advanced wiring
(parameter services, custom guard conditions). Don’t use during
spin from another thread; the runtime is
single-threaded.
Sourcepub fn component_count(&self) -> usize
pub fn component_count(&self) -> usize
Number of registered components.
Sourcepub fn register_node<C: ExecutableNode + 'static>(
&mut self,
) -> NodeResult<RegisteredNode<C>>where
C::State: 'static,
pub fn register_node<C: ExecutableNode + 'static>(
&mut self,
) -> NodeResult<RegisteredNode<C>>where
C::State: 'static,
Register a [Node] (which must also be
ExecutableNode) into this runtime. Builds the
component’s State (via ExecutableNode::init) and
walks [Node::register] over the live executor — every
declared node / pub / sub / timer materialises as a real
executor handle, and subscription + timer callbacks are wired
to dispatch into ExecutableNode::on_callback.
Sourcepub fn spin_once(&mut self, timeout: Duration) -> Result<(), ExecutorError>
pub fn spin_once(&mut self, timeout: Duration) -> Result<(), ExecutorError>
Drive one executor iteration + a tick per registered
component.
Sourcepub fn dispatch_callback(&mut self, cb_id: &str, ctx: &mut CallbackCtx<'_>)
pub fn dispatch_callback(&mut self, cb_id: &str, ctx: &mut CallbackCtx<'_>)
Phase 216.B.3 / C.3 follow-up — route a signaled callback to every registered component slot.
The RTIC (nros-board-rtic-stm32f4) and Embassy
(nros-board-embassy-stm32f4) dispatch tasks dequeue a
nros_platform::SignaledCallback envelope from their SPSC
queue / Embassy channel and need a routing entry point that
hands the callback off to the right Node’s on_callback
trampoline. This method is that entry point.
§Strategy — linear scan
Each registered slot’s dispatch_fn is the codegen-emitted
d() trampoline from nros::node!() (see
packages/core/nros-macros/src/lib.rs). That trampoline calls
<NodeTy as ExecutableNode>::on_callback, whose body
matches on the callback’s own tag set
(Subscription / Timer / Service / Action ids) and is a
no-op for non-matching cb_ids. So a linear scan across every
slot is correct — each slot self-filters and at most one
component actually acts on a given cb_id. A focused
cb_id → slot index is a separate follow-up; the trampoline’s
tag dispatch already gates the real work cheaply (string
compare on statically known literals), so the linear scan is
the minimum-viable wiring that closes the conceptual gap left
by the B.3 / C.3 skeleton emits.
§Borrow semantics
Each ComponentCell’s slot lives behind a RefCell; the
per-slot dispatch takes try_borrow_mut and is a no-op on
re-entrancy. The runtime is single-threaded by construction
(the dispatch task owns it via &mut self), so the borrow
always succeeds in normal flow.
Sourcepub fn spin(&mut self) -> Result<(), ExecutorError>
pub fn spin(&mut self) -> Result<(), ExecutorError>
Spin until the executor’s halt flag is raised. Hosted-only; on
bare-metal the BSP wraps spin_once in its own loop.
Trait Implementations§
Source§impl NodeDispatchRuntime for ExecutorNodeRuntime
impl NodeDispatchRuntime for ExecutorNodeRuntime
Source§fn spin_once(&mut self, timeout_ms: u32) -> Result<(), ()>
fn spin_once(&mut self, timeout_ms: u32) -> Result<(), ()>
timeout_ms
milliseconds. Ok(()) on a clean spin (including timeout);
Err(()) if the executor surfaces a spin error. Read moreSource§fn executor_handle(&mut self) -> *mut c_void
fn executor_handle(&mut self) -> *mut c_void
*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). Read moreSource§fn observed_callback_counts(&self) -> (usize, usize)
fn observed_callback_counts(&self) -> (usize, usize)
Source§fn signal_callback(&mut self, _cb: SignaledCallback<'_>)
fn signal_callback(&mut self, _cb: SignaledCallback<'_>)
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
fn dispatch_strategy(&self) -> DispatchStrategy
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.