Expand description
§uiharu
A streaming protocol decode engine for logic analyzer software, automated tests and waveform tools. Written in Rust and licensed under Apache-2.0.
Decoders process blocks of logic samples, exchange typed events through bounded queues with backpressure, and compose into a checked decode graph. Events within each output stream are independent of block boundaries and reader pauses.
cargo add uiharuUsing a published crate requires Rust 1.90 or newer. Node/pnpm is needed only to develop the TypeScript decoders in a source checkout; published packages already contain the generated Rust.
§A typed SPI pipeline
use std::sync::Arc;
use uiharu::{Graph, SignalItem, SourceSpec, TimeBase};
use uiharu::protocols::spi::{Spi, SpiConfig};
let mut graph = Graph::new();
let source = graph.source(SourceSpec::new("logic", 4, TimeBase::new(25_000_000)))?;
let spi = graph.add(Spi::new(SpiConfig::default())?);
graph.connect(source.samples, Spi::input(spi))?;
let output = graph.expose("spi", Spi::events(spi))?;
let mut pipeline = graph.build()?;
let events = pipeline.exposed(output).expect("exposed once");
// For each bit-packed LogicBlock supplied by your capture source:
pipeline.push(source.id, SignalItem::Data(Arc::new(block)))?;
pipeline.run();
while let Some(item) = events.next() {
// Typed SPI events, gaps, progress and end-of-stream notifications.
println!("{item:?}");
if matches!(item, uiharu::Item::End(_)) {
break;
}
}The complete SPI example generates and decodes a transaction. Add another decoder to consume the SPI events, for example SPI NOR flash, SD cards or an nRF24L01+ radio.
§Features
| Feature | Default | Provides |
|---|---|---|
protocols | Yes | Built-in decoders under uiharu::protocols |
registry | No | Named decoders, UI metadata, JSON pipeline descriptions and runtime IR loading under uiharu::registry |
testing | No | Decoder acceptance harnesses under uiharu::testing, intended for dev-dependencies |
With default-features = false, only the core runtime is included. For a configurable
application, run cargo add uiharu --features registry.
§Command line
cargo install uiharu-cli --locked
uiharu gen flash.bin
uiharu decode flash.bin --stats§Documentation and compatibility
- Engine guide and protocol coverage
- Architecture
- Writing decoders
- TypeScript DSL and versioned IR
- Release and compatibility policy
The uiharu-* crates share a release version independent of the HSync application.
Before 1.0, a minor version may introduce incompatible API changes; patch releases
preserve API compatibility. IR format compatibility is identified separately by
the module’s ir field and uiharu_ir::IR_VERSION.
Re-exports§
pub use uiharu_protocols as protocols;pub use uiharu_registry as registry;
Modules§
- dsl
- The runtime of decoders compiled from the DSL: what the backend emits generated code
against (
docs/dsl.md§3 and §5). - exec
- Running a built graph: feeding sources, polling the nodes until nothing can move, and reading the exposed outputs.
- graph
- Building a decode graph: sources of logic samples, decoder nodes, the connections between their typed ports and the outputs exposed to the caller. Connecting checks that the ports agree on the schema and that the input’s requirements are met; building checks that every input is connected, that the graph has no cycle and that each node reads one time domain.
- hex_u64
- Integers wider than JSON readers keep exactly.
- node
- Decoders as the executor runs them: a node declares its ports, is started with its ports
bound to queues, and runs as one future that reads through an
Inboxor aSignalCursorand writes through anOutbox. - schema
- What ports carry and what they require of each other: the identity of an event schema, the properties an output declares (word width, bit order, which lines are present …) and the requirements an input places on them. The graph checks them when ports are connected.
- signal
- Logic samples as decoders read them: blocks of bit-packed samples, and the cursor that walks a stream of blocks looking for edges and reading levels.
- stream
- Event streams: the envelope every event carries, the control items that travel with events, and the bounded broadcast queue that hands one producer’s items to every reader.
- testing
- Helpers for testing decoders: a one-source pipeline driven block by block, with the blocks cut to chosen sizes, gaps announced and the reader pausing between blocks, and the check the acceptance criteria call for — that none of this changes the events.
- time
- Time as decoders see it: ticks on a source’s sample clock, tick ranges and the time base that turns them into seconds. Decoders never work in seconds; everything they emit is placed in ticks so that results stay exact and comparable.
Structs§
- Broadcast
- A bounded queue from one producer to any number of readers.
- Channel
Mask - A set of channels: bit
istands for channeli. - DynExposed
Ref - An output exposed through
Graph::expose_dyn, read withPipeline::exposed_dyn. - DynInput
- An input port named at run time; see
Graph::input. - DynOutput
- An output port named at run time, for graphs built from a description rather than from
typed code; see
Graph::outputandGraph::connect_dyn. - Event
- An event with its envelope: where on the signal it comes from, when it became certain and its position in the stream.
- Exposed
- The caller’s reader on an exposed output.
- Exposed
Ref - An exposed output, read through
Pipeline::exposed. - Graph
- A decode graph under construction.
- Graph
Config - Limits every node and queue of a graph shares.
- Inbox
- A node’s reader on one of its input queues.
- Input
Ref - An input port reading
Tevents. - Input
Spec - An input port as a node declares it.
- Io
- The queues bound to a node’s ports, handed to
Node::start, with what the node may need to know about them: the time base its inputs are on and the properties of the outputs they read. - Levels
- The levels of every channel at one tick: bit
iset means channeliis high. - Logic
Block - A block of samples:
lenticks fromstartonchannelschannels, bit-packed per channel, least significant bit first. - Logic
Block Builder - Builds a
LogicBlocksample by sample. - NodeCx
- The executor’s side of a node: its budget, why it last paused and how much it has done.
- NodeId
- A node in a graph.
- Node
Spec - Outbox
- A node’s writer on one of its output queues.
- Output
Ref - An output port carrying
Tevents, asGraph::connectandGraph::exposetake it. - Output
Spec - An output port as a node declares it.
- Pipeline
- A built graph, ready to take samples and run.
- Progress
Sink - An output seen only as a place to pass progress on, for cursors over a contract. A cursor
passes the progress it meets inside a frame on through it, held back to what the decoder
has read through the cursor and not reported yet: what it consumed since it last took the
provenance (
consumed()), and what it says it still holds (ProgressSink::hold) when it took provenance early for an event still to come. Made byOutbox::progress_sink; clones share their state. - Props
- The properties of an output port, by name.
- Provenance
- Where an event comes from: the ticks it covers and when it became certain.
- Queue
Stat - The state of one queue.
- Reader
Id - A reader’s identity on a
Broadcast. - Requires
- The requirements of an input port, by property name.
- RunReport
- What one run of the pipeline did.
- Schema
Id - The name and version of an event schema, such as
spi.eventsversion 1. Two ports are compatible only when both agree. - Signal
Cursor - A decoder’s view of a source: a position in its samples, with the levels just before it.
- Source
Handle - The source as added to a graph: its id and its output.
- Source
Id - A source of logic samples in a graph.
- Source
Spec - A source of logic samples, as
Graph::sourcetakes it. - Stats
- The state of every queue of a pipeline.
- Tick
- A sample index on a source’s clock, counted from the first sample the source produced.
- Tick
Range - A half-open range of ticks,
start..end. Serialized as the pair[start, end]. - Time
Base - The clock of a source: how many ticks make a second.
Enums§
- Block
Error - Why samples do not make a block.
- Change
- What a wait for an edge finds.
- Graph
Error - Why a graph cannot be built as asked.
- Item
- What travels along a stream: events, and the control items that frame them.
- Prop
Value - A property of an output port.
- Push
Error - Why a source did not take an item.
- Requirement
- What an input requires of one property of the output it is connected to.
- Sample
- What reading the levels at the cursor finds.
- Signal
Item - What a source feeds into a pipeline.
- Wait
- What a node is waiting for when its future returns
Pending.
Constants§
- LOGIC_
SAMPLES - The schema of a source’s output: blocks of logic samples.
- MAX_
CHANNELS - The most channels a source may have.
Traits§
- Event
Schema - The payload type of an event stream, tied to its schema.
- Node
- A decoder, or any other step of a decode graph.
- Readable
- An input a node can wait on: an inbox, or a signal cursor.
Functions§
- ready_
all - Waits until every input in
inputshas something to read. A node with several inputs waits on all of them, then takes the item whose time (Item::time) is earliest — the one with the lowest index on a tie — so that what it does depends on the items alone, never on which input happened to fill first.
Type Aliases§
- Node
Future - The future that runs a node.