Skip to main content

Module early

Module early 

Source
Expand description

Records raised before any sink was installed.

§The problem this exists for

crate::init publishes the sink list. A record raised before that call has nowhere to go, and for most of this crate’s life it was constructed, dispatched and DROPPED — silently, and invisibly to its author, who cannot know what the board did before reaching their code.

Issue 0708 answered by requiring every board boot funnel to call init_default(), gated on funnels spelled pub fn run*. That is a SEARCH for boot paths and it kept losing: NuttX’s funnel is pub extern "C" fn nsh_main, and three board crates did not link nros-log in the configuration holding the funnel at all.

Issue 0710 answered by having dispatch install the platform sink itself. That removed the search — but it put nros_platform_log_write on a path EVERY binary executes, which turned a pluggable delivery into a LINK-TIME requirement. Seven test targets in nros-rmw-cffi and most of nros-tests stopped linking under check-workspace-features, and no Cargo feature can fix that: nros-platform-cffi and nros-rmw-bridge enable nros-node/rmw-cffi unconditionally, so feature unification turns any forwarded gate back ON for every member of a workspace build. A feature is a property of the BUILD; what the question needs is a property of the BINARY.

§A funnel is not always a board method — issues 1048 and 1123

The search above kept losing for one more reason, and it is worth naming because it defeats the obvious grep: not every boot funnel lives in a board crate. nros::main! emits a different entry shape per framework, and two of them reach no BoardEntry method at all —

  • Framework::Zephyr (and its single-node sibling nros::zephyr_component_main!) emits rust_main directly, because Zephyr owns the C main and a Rust staticlib cannot take it over. That is why nros-board-zephyr has only run_tiers to install from, and why a single-tier pure-Rust Zephyr image published no sink list for two phases (issue 1123) while its log::info!s worked fine.
  • a [[bridge]] system replaces the register/spin body with nros_bridge::run_from_config_str, so it reaches no board either.

Both now call nros_platform::log::init_default() — reached through nros-platform (which re-exports nros_platform_cffi::log) because that is the crate a generated Entry and the Zephyr example leaves already declare; giving each leaf a nros-platform-cffi dep of its own is the link-time requirement 0710 rejected.

So the enumeration is board crates PLUS the framework arms of nros-macros’ main_macro.rs PLUS nros’ entry macros. Sweep it with:

grep -rn 'Framework::[A-Za-z]* => ' packages/core/nros-macros/src/main_macro.rs
grep -rn 'init_default()' packages/boards packages/core/nros-macros packages/api/nros

§What this does instead

Hold the records. A record raised with no sinks installed is copied into a bounded static ring here; crate::init drains it into whatever sinks the board actually chose. Nothing is dropped, no board can forget, and this crate touches no platform symbol to do it — the facade stays a facade.

It is also STRICTLY better than installing a default sink was: the early records land in the sink the board picked, rather than in whichever one dispatch guessed before the board had spoken.

§Cost, and how to decline it

EARLY_DEPTH * (format buffer + name + header) of static RAM, all of it in .bss. The depth is the NROS_LOG_EARLY_RECORDS knob (issue 1037; builtin 4, resolved by build.rs on the RFC-0049 ladder — it replaced the early-records-<N> features), because a 64 KB MCU and a Linux host do not want the same number. 0 declines the buffer entirely and restores the pre-0708 behaviour of dropping, with the count below still kept so the loss is at least reportable.

Overflow is counted, never silently absorbed: overflowed returns how many records did not fit, and init reports it through the freshly installed sinks.

Functions§

early_depth
Records held before init. See the module docs for the trade.
overflowed
How many early records did not fit and were lost.