Skip to main content

RticBoardEntry

Trait RticBoardEntry 

Source
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_rx_irq() { ... }
    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). Its Embassy sibling, EmbassyBoardEntry, was retired with the nros::main! Embassy branch (issue 2134).

Required Associated Constants§

Source

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§

Source

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.

Source

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.

Source

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.

Source

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.

Source

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§

Source

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

Source

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§

Source

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

Source

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

Source

fn on_rx_irq()

phase-521 W6 (RFC-0113 D4) — the network link’s receive interrupt. Invoked from the proc-macro-emitted #[task(binds = <rx_irq>, priority = 2)] hardware task. It masks or acknowledges the source; the interrupt itself is what ends the run task’s park (a wfi in the port’s wake object), so an arrival is dispatched when it lands rather than at the next tick.

Default: no-op, for boards whose RticBoardSpec declares no rx_irq.

Source

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

Implementors§