Validate configuration through its owning schemas and keep board declarations separate from shared F722 resource ownership. Bound USB transitions, isolate transport failures and retain restart-only activation. Migrate navigation and flight consumers with the sensor and schema contracts. Require explicit installation data and synchronous output authority; board motor outputs remain inhibited. Validation: assembled-prefix host tests, strict Clippy, platform/USB tests and both ARM release builds. Final-source coverage and scoped Miri/Kani evidence are retained separately from hardware qualification.
4.2 KiB
Logs
Logging macros work on host and flight targets:
kaptan_log::debug!("estimator waiting for IMU");
kaptan_log::info!("configuration loaded");
kaptan_log::warn!("range aid stale");
kaptan_log::error!("sensor transfer failed");
kaptan_log::trace!("prediction step complete");
All five macros emit LOG; their level never selects a different wire
message. When a reportable firmware error escapes a
#[kaptan_err_reportable::propagate] function, it makes one bounded admission attempt
to the separate ERROR ingress.
kaptan-log formats each event once into fixed 160-byte UTF-8 storage. Its core
storage and admission paths use no allocation or blocking, and do not send
MAVLink, change flight state or touch DMA. Formatting invokes caller-supplied
Display implementations, which may allocate, block, ignore fmt::Error or do
unbounded work. Overflow stops formatters that propagate the error and latches
truncation even if a formatter ignores it. Bounded storage is not a universal
worst-case execution-time guarantee. Producers must choose formatters suitable
for their execution context.
The composition fans the event into each enabled sink. The MAVLink worker drains
its bounded sink queue. Reportable-error records contain the explicit ID and a
static reference to the reporting point until the MAVLink adapter copies its
file:line into the 96-byte raised_at field.
Logs and reportable errors use independent fixed atomic
ingresses; interrupt and worker producers make one nonblocking admission
attempt, and only the MAVLink worker encodes or transmits a retained event.
Panic and hard-fault paths still do not attempt live telemetry.
Receiver contract
definitions/publish/log.xml and definitions/publish/error.xml define the
separate ordinary-log and reportable-error publications:
LOG { level, flags, message_length, message[160] }
ERROR {
error_id, raised_at[96]
}
A GCS decoder generated from the same kaptan.xml revision must validate
message_length <= 160 for LOG. ERROR.raised_at is a
zero-padded UTF-8 file:line prefix; receivers use bytes before the first zero,
or the complete field when no zero is present.
LOG.level is the typed severity-ordered Kaptan wire enum Trace (1), Debug
(2), Info (3), Warn (4), or Error (5). Off (0) is a filter-only sentinel and
is never emitted as a LOG event. LOG.flags currently owns only the
Truncated bit (1).
error_id is the stable nonzero catalog number explicitly assigned to the
Rust error variant. Renaming or reordering a variant does not change it.
raised_at identifies the reporting point where the Err entered
diagnostics. Protocol failures remain in their owning response; for example, a
rejected KCFG upload returns a FILE_CONTROL failure and readable
bounded detail.
Delivery is bounded and lossy under link pressure. Heartbeat and sensor
telemetry use separate paths. Logs have no publication rate setting and are
not periodic streams. The worker offers each retained event to USB and every
MAVLink UART, then removes it once at least one transport admits it. Admission
does not prove receipt or delivery to every link. If none admits it, the event
remains pending. Opening USB does not take diagnostics away from UART.
Filtering
The single restart-only mavlink.logging.level_filter field uses Off (0),
Trace (1), Debug (2), Info (3), Warn (4), and Error (5). Info, for example,
accepts Info, Warn, and Error log events. Off suppresses LOG on MAVLink
without suppressing reportable ERROR events or logs sent to another
sink. There is no separate enable flag and no MAVLink-specific set of extra
runtime log levels. F722 uses the validated boot-active filter. Empty storage
uses factory values. Invalid storage selects the setup fallback, which also
uses the factory filter but disables UART roles. Saved changes and factory
reset do not alter the active filter until reboot. See
configuration recovery.
Events retain the compact typed Level and sink configuration retains the
compact typed LevelFilter. Schema metadata supplies the filter choices to the
configurator.
Only the MAVLink adapter converts the five event levels to the typed Kaptan
wire enum.
The log ingress is transport-neutral and unfiltered.