Axiom One
Embedded applications repeatedly need small, well-bounded control, signal, sequence and state operations without adopting a framework or paying for unused code.
A dependency-free C99 static library of 22 focused deterministic primitives. Its ONE modules keep state with the caller, use no heap, timers, callbacks or I/O, and expose a plain C API that can be included as one umbrella header or as narrow module headers.
Small functions; caller-owned state
Axiom One is a dependency-free C99 static library of focused embedded primitives. Modules expose plain C APIs, retain no hidden global mutable state and do not own a heap, timer service, callback loop or I/O path.
The library uses the ONE prefix in function names and module identifiers. Public headers can be included from C++ and keep C linkage; the implementation remains C99.
Four families of bounded behavior
Scheduling
ONEARB, ONEBACKOFF, ONERATE and ONEINIT cover round-robin arbitration, retry delay, fractional rate generation and ordered initialization.
Signal and numeric
ONEEMA, ONEOUTLIER, ONEDEAD, ONEHYST, ONESLEW, ONEQUANT and ONESCALE cover filtering, input validation, thresholding, hysteresis, bounded movement, quantization and conversion.
Sequence and protocol
ONESTALE, ONEVOTE, ONEWINDOW and ONESEQ handle timestamp freshness, sliding votes, replay windows and cyclic sequence numbers.
State containers
ONEBUF, ONEDBUF, ONEFIELD, ONEIDX, ONESET, ONESTAT and ONETRACE provide fixed buffers, packed values, lookup schemas, sets, records and ring traces.
The umbrella header does not pull in every module
Applications can include <one.h> for convenience or a narrow header such as <one/slew.h>. The repository documents static-library linking where the linker extracts only object members required by referenced functions. A symbol's presence in the umbrella header does not itself mean the implementation for every module is linked.
The footprint report builds one consumer per module and representative combinations, then compares executable and text sizes with linker-map evidence. Those results apply to the report's compiler, linker, build configuration and targets; they are not universal MCU flash figures.
#include <one/slew.h>
uint32_t current = 0u;
one_status_t status = one_slew_u32(
100u, 10u, 20u, ¤t);
/* state and error handling stay with the caller */Initialization and status handling belong in the integration
Mutable one_*_t state objects belong to the application and should be initialized before first use unless a module is stateless. The library does not synchronize caller-owned state. Concurrent access therefore needs application-level synchronization.
Modules may return a typed status, a boolean or a direct value when no error condition exists. A non-success status generally means output or state must not be assumed changed unless that module documents a different contract. Invalid configuration and NULL are ordinary recoverable errors where the API exposes them.
uint32_t, int32_t and size_t. Numeric width is part of the module contract.Behavior, toolchain and size are separate checks
The repository documents Debug, Release, AddressSanitizer and MSVC /W4 /WX configurations. Tests target public functions, errors, state transitions, boundary values and independent reference models for arithmetic and sliding-state behavior. Exhaustive examples include arbitration across request masks and broad reference-model checks for backoff, rate, hysteresis, slew, outlier and voting operations.
The footprint report is a measured build artifact. Test coverage and target builds show evidence for exercised configurations; they do not establish timing or binary size on every embedded compiler and linker.
Primitives do not replace system policy
- The caller owns mutable state, initialization order and synchronization.
- The library supplies no clock, timer service, callback scheduler, random source or I/O.
- Each module has its own numeric limits, statuses and failure semantics; read its narrow header and API guide.
- Static linking can reduce unused object extraction, but final footprint depends on toolchain and build configuration.
- A deterministic primitive does not make the surrounding application deterministic by itself.