Skip to main content

Crate consortium_dbg

Crate consortium_dbg 

Source
Expand description

defmt logging over shared memory: the CDBG ring, its firmware-side global_logger, its host-side reader/decoder, and an optional panic handler.

§The problem

A coprocessor on a Consortium SoC usually has no UART of its own to log through, or has one already spoken for. But it does share memory with a Linux-capable core that has a filesystem, a clock, and somewhere to put logs. So the debug path runs the same way as everything else here: firmware writes into a shared window, Linux reads it.

defmt is the right encoder for the firmware end. Format strings and type metadata stay in the ELF and never reach the wire, so a log line costs a few bytes and no formatting code — which is what makes logging affordable on a Cortex-M at all. The cost is that the bytes are meaningless without the ELF they came from, so the host side needs a decoder.

§Architecture

 firmware (no_std)                        Linux / host
 ────────────────────                     ─────────────────────
 defmt::info!(..)
   └─ logger::ConsortiumLogger            host::HostRing
        (global_logger; rzcobs-encodes      (validate CDBG, drain frames)
         one frame, wraps it in a             └─ host::DefmtSession
         packet, appends to the ring)             (decode against the ELF)
                   │                                      │
                   └────────  CDBG shared window  ────────┘
                         descriptor + circular buffer
 panic::(handler)  ─ latches Flags::Panic in the descriptor
ModuleRole
configThe ring base/length ConsortiumLogger::init records.
descriptorThe CDBG descriptor and single-writer/single-reader ring rules.
packetPer-frame envelope inside the ring.
ringRingWriter / RingReader: the ring as a non-waiting transport.
loggerFirmware #[global_logger]; encodes and appends.
hostHost-side validation, draining, and defmt decoding.
panicOptional #[panic_handler] that records a crash in the ring.

§The ring as a transport

The ring is a memory-backed link with no doorbell, so it implements consortium-core’s non-waiting pair, the same base the IPC shared-memory transport and the SCMI agent build on. ring::RingWriter is a TrySendTransport: appending a frame never waits, and a full ring is TryError::WouldBlock with Overflow latched, which is what lets the #[global_logger] and the panic handler use it. ring::RingReader is a TryRecvTransport that copies into a caller buffer without allocating; the host’s HostRing is built on it. Both are generic over any coherent consortium_core::Region and refuse a cached one: the CDBG layout shares cache lines between writer- and reader-owned fields, so flushes would clobber each other. The logger maps its ring as an UncachedRegion, as it always has.

§Descriptor discipline

The ring has exactly one writer (firmware) and one reader (host), and there is no lock. What keeps it correct is that each side only mutates the fields it owns: the writer owns write_ptr, capacity, and flags; the reader owns read_ptr; write_ptr == read_ptr means empty. Preserve that split when changing anything here — it is the whole synchronization story.

§Configuration

Layout comes from the manifest, not from the firmware source. csti build lowers [dbg.<core>] in Consortium.toml into the generated init(), which calls ConsortiumLogger::init(base, len) first thing. Until that call, the logger and the panic handler are no-ops, so a firmware crate built without generated code still links and runs; it just logs nothing.

§Features

Defaults are host and logger.

FeatureEffect
loggerFirmware #[global_logger] writing into the ring.
hostHost-side HostRing reader; implies std.
decodeAdds defmt-decoder/defmt-parser for host::DefmtSession; implies host.
panic-handlerInstalls #[panic_handler]; implies logger.
arch-cortex-mInterrupt-disable and halt for Cortex-M. Required by panic-handler.
arch-riscvInterrupt-disable and halt for RISC-V. Required by panic-handler.

panic-handler needs exactly one arch feature, and the two arch features are mutually exclusive; both conditions are compile_error!s below rather than link-time surprises.

§Testing

cargo test -p consortium-dbg              # descriptor, ring, packet
cargo test -p consortium-dbg --features decode
just test dbg host

Host-side tests cover descriptor initialization, ring read/write behaviour, decoding fixtures, and the overflow/error flags — no target hardware needed.

Modules§

descriptor
Shared memory defmt descriptor definitions.
host
A-core shared-memory reader for the CDBG debug ring.
logger
Firmware-side defmt sink: the #[global_logger] that appends encoded frames to the CDBG ring.
packet
Per-frame envelope inside the CDBG ring.
ring
The CDBG ring as a Consortium transport.
utils
Byte-at-a-time volatile accessors for the shared debug region.