pub trait RticBoardEntry: Board {
type Pac: 'static;
type Core: 'static;
type Executor: 'static;
type Boot: 'static;
type Runtime: NodeDispatchRuntime + 'static;
const DISPATCHERS: &'static [&'static str];
// Required methods
fn init_hardware(
device: Self::Pac,
core: Self::Core,
) -> (Self::Boot, Self::Runtime);
fn open_executor(boot: Self::Boot) -> Self::Executor;
// Provided methods
fn init_hardware_with_deploy(
device: Self::Pac,
core: Self::Core,
_deploy: &DeployOverlay,
) -> (Self::Boot, Self::Runtime) { ... }
fn on_tick() { ... }
fn on_interrupts_live() { ... }
}Expand description
Board-side hook for RTIC integration. The nros::main!()
proc-macro (216.B.3) generates a #[rtic::app] module that calls
Self::init_hardware from inside the framework-generated
#[init] body and wires the returned pair into RTIC #[local]
storage.
Distinct from super::BoardEntry (board-owns-spin) and
[planned] EmbassyBoardEntry (216.C.1, executor-owns-spin via
embassy_executor::Spawner).
Required Associated Constants§
Sourceconst DISPATCHERS: &'static [&'static str]
const DISPATCHERS: &'static [&'static str]
RTIC dispatchers = [...] list, declared at the board layer
so each chip pins its own interrupt slots (e.g. &["USART1", "USART2"]). The proc-macro splices this into the generated
#[rtic::app(dispatchers = …)] attribute.
Required Associated Types§
Sourcetype Pac: 'static
type Pac: 'static
Chip Peripheral Access Crate handle (e.g.
stm32f4xx_hal::pac::Peripherals). Whatever the RTIC
#[rtic::app(device = …)] attribute expects as the device
peripheral struct.
Sourcetype Core: 'static
type Core: 'static
Core peripheral handle. Typically cortex_m::Peripherals on
Cortex-M chips but kept abstract so nros-platform doesn’t
take a transitive cortex_m dep that every POSIX / Zephyr /
RTOS consumer would inherit.
Sourcetype Executor: 'static
type Executor: 'static
Executor type the board hands back from
open_executor. Concrete board impls plug in
nros::Executor; the assoc type keeps the layering clean
(nros-platform does not depend on nros). The proc-macro drives the
opened executor’s spin loop in the __nros_run task.
Sourcetype Boot: 'static
type Boot: 'static
#178 — hardware-ready deferred-open carrier returned by
init_hardware. Holds whatever the board needs
to open the executor later (locator / domain / node-name — all
'static), but performs no blocking network I/O itself.
The split exists because Executor::open does a blocking zenoh
session open (a TCP connect driven by the platform poll loop, which
needs the timer tick + RX interrupt), and RTIC runs #[init] with
interrupts masked. The proc-macro stashes this carrier in RTIC
#[local] storage from #[init], then the __nros_run task calls
open_executor on its first poll — after init
returns and interrupts unmask.
Sourcetype Runtime: NodeDispatchRuntime + 'static
type Runtime: NodeDispatchRuntime + 'static
Dispatch sink the proc-macro wires into RTIC #[local]
storage. Required to implement
NodeDispatchRuntime so signaled callbacks queued from
RTIC tasks reach the registered Node pkgs.
Per Phase 216.A.2, NodeDispatchRuntime already carries
signal_callback + dispatch_strategy; the RTIC runtime
impl uses DispatchStrategy::Deferred and routes signals
through a heapless::spsc::Producer into an RTIC software
task (see Phase 216.B.2).
Required Methods§
Sourcefn init_hardware(
device: Self::Pac,
core: Self::Core,
) -> (Self::Boot, Self::Runtime)
fn init_hardware( device: Self::Pac, core: Self::Core, ) -> (Self::Boot, Self::Runtime)
Run from inside the proc-macro-generated #[init] body.
Brings up clock / pin / transport hardware and splits the dispatch
SPSC, then returns the (Boot, Runtime) pair the macro stashes in
RTIC #[local] storage. #178 — this must NOT open the executor (that
blocking connect is deferred to open_executor,
called from the __nros_run task where interrupts are live).
Sourcefn open_executor(boot: Self::Boot) -> Self::Executor
fn open_executor(boot: Self::Boot) -> Self::Executor
#178 — open the executor from the Boot carrier.
This performs the blocking zenoh session open (Executor::open),
so it MUST be called from the __nros_run task, NOT #[init]:
RTIC masks interrupts during #[init], which starves the platform
poll loop (no timer tick / RX IRQ) and deadlocks the TCP handshake.
The proc-macro calls this on the task’s first poll, once init has
returned and interrupts are unmasked.
Provided Methods§
Sourcefn init_hardware_with_deploy(
device: Self::Pac,
core: Self::Core,
_deploy: &DeployOverlay,
) -> (Self::Boot, Self::Runtime)
fn init_hardware_with_deploy( device: Self::Pac, core: Self::Core, _deploy: &DeployOverlay, ) -> (Self::Boot, Self::Runtime)
Like init_hardware but applies a deploy-metadata
overlay (Phase 244.D1) to the board’s compiled-in net/locator Config
before opening the executor. nros::main!() calls THIS from the
generated #[init] body, passing the
[package.metadata.nros.deploy.<board>] block.
The default ignores deploy and forwards to
init_hardware, so existing RTIC boards are
unchanged. Boards with a baked net Config (the bare-metal firmware
boards) override it so each Entry pkg can pin its own ip / locator /
gateway — required when two RTIC firmwares share one board on the same
QEMU network (e.g. the talker-rtic / listener-rtic pub/sub pair).
Sourcefn on_tick()
fn on_tick()
Phase 289 (#178 layer 3) — clear + re-arm the board’s periodic tick
IRQ. Invoked from the proc-macro-emitted
#[task(binds = <tick_irq>, priority = 2)] hardware task, whose only
job is waking the wfi inside __nros_run’s connect/poll busy-waits.
The board arms the timer itself in
init_hardware (it owns the PAC); this hook
only handles the per-interrupt acknowledge. An unacknowledged flag is
an IRQ storm that starves the priority-1 run task — always clear it.
Default: no-op, for boards whose RticBoardSpec declares no
tick_irq (the macro then emits no tick task at all).
Sourcefn on_interrupts_live()
fn on_interrupts_live()
Phase 289 (#178 layer 2) — called once at the top of the
__nros_run task, after #[init] returned and interrupts unmasked,
BEFORE open_executor. The place to install
idle-yield hooks that require a live IRQ source (e.g. the mps2
board’s enable_wfi_idle(), which makes the zenoh connect busy-wait
wfi between iterations so host-timed slirp packets can arrive under
QEMU -icount). Installing wfi with no armed IRQ deadlocks — the
tick task exists precisely so this hook is safe to run here.
Default: no-op.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.