Source-adjacent contracts

The layer README files remain canonical beside their implementation. The following inclusions read those exact files rather than copying a second contract. Relative source links are bound to the website source revision.

Core

Core contracts

C11 caller-owned request admission, stable control identities, completion state and monotonic absolute deadlines. No devices, OS scheduler, allocation or global registry. Public interfaces are in include/nexus/core.

REJECTED retains no references. An accepted chain borrows request and buffers until acquire-observed SETTLED. SETTLED is its last request access. Cancel/timeouts never revoke a borrow; failed drain keeps QUARANTINED storage alive. Producers wait on latched state; a single executor services the operation. Queue adapters own their outer request and use explicit inner provider metadata where needed.

tests/contracts/core_contract_test.c executes publication, admission, wrapping time arithmetic and terminal-state invariants. Host results do not prove MCU interrupt ordering or worst-case execution time.

Arch

CPU-local primitives

Nexus::Arch exposes saved interrupt masks, exact exception identity, current privilege, ordering barriers and an optional already-enabled DWT cycle snapshot. It does not call I/O, OS or vendor SDK code. One compile-time Cortex-M primitive implementation covers M0/M0+/M3/M4/M7/M23/M33/M55/M85, including ARMv8.1-M Mainline compiler profiles. STM32F407 and GD32F470 maintain the initial platform scope; G474, H743 and U575 provide explicit reference slices described in the support matrix. CPU support does not extend those SoC or Board slices. The separate CPU runtime assembly selects Core/Arch and optional OS software for all nine cores without creating a SoC, Board, startup or factory. See CPU contracts and the runtime assembly example.

Save/restore tokens on the same CPU/thread in strict reverse order. Cortex-M preserves incoming PRIMASK and does not overwrite BASEPRI/FAULTMASK where those registers exist. Only privileged Task/configurable-IRQ callers may change masks. NMI and HardFault remain unmasked and must not access this protected metadata. Keep metadata sections short: no blocking, allocation, large copies, kernel calls or user callbacks. A saved Arch token is not a kernel critical-section token or an SMP lock.

Mask/context queries let blocking I/O reject contexts that prevent its progress. The read-only mask snapshot distinguishes PRIMASK, BASEPRI and FAULTMASK; it is not a restore token and does not freeze interrupt or security-world execution. Baseline M0/M0+/M23 queries never read absent BASEPRI/FAULTMASK. Handler mode is privileged even when CONTROL.nPRIV describes an interrupted unprivileged Thread. An exception number identifies the current CPU/security state; it does not grant permission to call a kernel ISR API or coordinate another security world. DMB/DSB/ISB encode different ordering guarantees; they do not prove peripheral or DMA quiescence. DWT snapshots require an explicit reviewed CPU capability and privileged access. A disabled capability emits no DWT reads. Snapshots do not enable or reset the counter and are not monotonic deadlines. Their wrap/frequency limits are documented in the header. Reviewed capabilities are explicit CPU facts, never inferred by probing arbitrary registers or enabling optional units.

sleep.h exposes two explicit shallow-sleep operations. The masked nx_arch_wait_for_interrupt() requires privileged Thread mode, PRIMASK=1, BASEPRI/FAULTMASK clear and SCR.SLEEPDEEP clear. It executes DSB/WFI/ISB without changing masks, clocks or pending interrupts. The caller owns the final readiness check and an enabled IRQ wake source; a pending enabled IRQ wakes WFI despite PRIMASK and runs after the caller restores its saved mask. nx_arch_idle_if_unchanged() instead requires all incoming masks clear, saves PRIMASK, rechecks an aligned published sequence with acquire semantics and sleeps only when it still matches the caller’s snapshot. It restores the exact incoming mask; the caller retries the authoritative predicate and supplies an IRQ timer for finite deadlines. This is one CPU and one security state’s publication domain. NMI/HardFault, DMA, SMP and other security-world publishers are excluded. Native reports unsupported. Compiler/model evidence does not qualify a concrete timer, clock continuity, physical power behavior or wake latency.

cache.h exposes distinct data clean, invalidate, combined maintenance and instruction synchronization. Every range must own complete reviewed 32-byte lines, fit the CPU address space and be quiescent across CPU/DMA/security users. The functions do not round ranges, enable caches or flush unrelated dirty lines. cache_control.h separately owns cold M7 transitions. The caller supplies one zero-initialized control object, masks configurable interrupts and excludes DMA and all other memory users. Trusted reset or a prior successful owned clean/disable establishes cold state; clear CCR bits alone cannot prove that foreign dirty lines are absent. Enable rejects pre-existing caches; disable cleans every reviewed data set/way and changes CCR in a leaf that cannot dirty its own stack. Failed partial changes retain cache/CSSELR recovery responsibility. Actual instruction audits verify addresses, loops and barriers at O0/Os/O2. Other CPU profiles remain unsupported by this cold-control API; their range maintenance capability does not imply a reviewed global cache transition. mpu.h retains distinct v7-format and v8 base/limit/MAIR encoders. Single-region programming requires an already masked privileged Thread and disabled MPU; actual TYPE bounds and fields are checked before writes. CTRL and incoming RNR are preserved. Memory policy and any later enable operation belong to the caller. The optional M0+ MPU uses the v7-format registers confirmed by CMSIS.

security.h identifies the reviewed image state and encodes explicit SAU regions. Only a Secure compiler/profile with reviewed SAU regions can program one owned region, while SAU is disabled and the privileged Thread has PRIMASK set. No API changes SAU CTRL/ALLNS, another region, Secure gateways or another world’s alias. NonSecure and single-domain images return unsupported without SAU MMIO. IDAU, overlap rules, memory permissions and gateway policy stay outside these mechanisms.

nonsecure.h supplies an instantaneous Secure Thread observation of a complete span using the actual CMSE NonSecure unprivileged read or read/write check. It needs no programmable SAU when an IDAU establishes attribution. Native, single-state and NonSecure images return unsupported without crossing domains. Success does not pin, copy, authenticate, exclude MMIO or freeze mappings, DMA and bus firewall policy. SoC and gateway owners must separately establish these conditions before accessing memory or performing an operation.

features.h reports immutable reviewed cache/MPU/DWT/security/SAU capabilities, not enabled state or hardware qualification. Native exposes the same APIs with absent-hardware results; pure encoders remain usable. Extending CPU mechanisms does not provide a SoC startup, vector table, clock tree, memory/DMA routes, Board wiring or an RTOS FPU/MVE context port. Each new platform must supply and verify those boundaries independently. Publication and RMW atomics have separate contracts in atomic.h; CPU-specific fallback never silently links libatomic. Aligned acquire/release word loads and stores do not mask IRQs. M0/M0+ RMW uses bounded saved-PRIMASK exclusion and restores the incoming mask; all concurrent users must be privileged local Thread/configurable-IRQ callers. NMI, HardFault, another core, DMA and another security world are outside this exclusion domain. Other maintained cores use compiler lock-free RMW; exclusive retries do not establish a fixed cycle bound. Initialize words before publication and retain their lifetime until every reader/writer has stopped.

Native models recursive exclusion and C11 fences; it does not model real NVIC, DMA, physical timing or signal-safe interrupts. Invalid restore nesting aborts in both Debug and Release. GoogleTest/GoogleMock compiles the real Cortex-M algorithm against a narrow register/instruction hardware boundary for nine CPU profiles; the normal ARM path inlines that boundary and never links the mocks. Native tests exercise real recursive exclusion, strict token nesting and context queries. Cache, MPU and security models mock only external CPU/MMIO operations and run the production C algorithms, including rejection before state changes. Pinned CMSIS core_cm0plus/7/23/33/55/85.h, mpu_armv7/8.h and cachel1_armv7.h establish the maintained register layouts. Actual IRQ latency, privilege transitions, DMA/cache coherency and CPU timing require HIL.

Typed I/O

Typed I/O

GPIO, UART, SPI, I2C, Flash, watchdog, EXTI, PWM and ADC expose C11 interfaces. Each selected instance has an immutable face with two pointers: shared read-only methods and a pointer to private provider state. Generated faces live in read-only storage; their state and selected buffers are private static objects in the generated translation unit. Manually assembled providers use storage supplied by their explicit constructor owner. A 32-bit target spends eight bytes of Flash per face; mutable state and exact-capacity buffers are separate. Method pointers are shared per provider and mode rather than repeated in every mutable instance.

Public operations check the face and dispatch its exact context. Different provider tables can coexist in one image without redefining public symbols. A missing optional method reports NX_ERROR_UNSUPPORTED; invalid faces reject before provider access. A method must preserve the public operation’s execution, deadline, buffer ownership and failure contract. Provider headers, register layouts and SDK types stay private.

Generated typed factory IDs select instances and distinguish SPI/I2C controllers from their child endpoints. Lookup returns a static identity. Platform start, request admission, service, recovery and stop remain explicit; lookup performs no hardware initialization, allocation, name search or locking. Faces remain valid while provider storage exists, so stopping requires caller and IRQ quiescence rather than promising that a pointer has been revoked.

Stream reserve, publish, acquire, release, abort and stop access constant metadata independent of block count. Stop checks an outstanding-block count; filling, ready and borrowed blocks remain counted until proved abort or matching release. It never scans the block array or revokes a loan under the interrupt mask. Storage overlap validation remains a cold assembly operation whose work grows with block count. This complexity contract is not physical IRQ latency or cycle qualification.

Default paths need no OS locks or hidden tasks. Requests and transfer buffers remain caller-owned; generated provider buffers are assembly-owned and separate. UART tracks physical TC separately from loaded bytes and request release; error-only RX events never invent data. SPI and I2C preserve their bounded polling contracts, and controller recovery never replays a failed transaction. Flash exposes physical geometry; products provide explicit restricted regions.

The Native model owns independent state per instance. Its explicit default fixtures support focused tests; generated assemblies use separate state and buffers. Native behavior, production-register fault models and ARM link fixtures establish software evidence. Board facts authorize reviewed physical routes; software-only fixtures do not establish PCB connectivity or physical timing.

OS adapters

Optional OS adapters

Thin wait/wake and per-object storage contracts. Baremetal has no scheduler; Native uses POSIX threads; FreeRTOS uses explicit static TCB, stack and queue storage selected by the caller. No universal maximum pool, hidden worker, default timer daemon or device dependency on OS.

Notifications are hints: arm/recheck the authoritative request predicate. Kernel ISR operations validate the selected syscall ceiling. Native task return ends the pthread; FreeRTOS wrappers publish completion and suspend until external deletion; ThreadX wrappers enter the kernel completion path. The one external lifecycle owner must successfully join before reclaiming wrapper, TCB or stack storage. Completion hints alone do not prove kernel detachment. Applications own scheduler start, workers, queue depth, fairness and shutdown progress.

The real FreeRTOS POSIX scheduler fixture validates host task/queue lifecycle. The default privileged runtime selects exact pinned kernel sources from validated CPU facts: CM0 for M0/M0+, CM3 integer context for M3 and M4 without FP, CM4F for M4 with FP, CM7/r0p1 for M7 with FP, and each CM23/33/55/85 NTZ port with its separate assembly file. Integer-only M7 uses a reviewed build-derived CM3 port with PRIMASK-preserving errata 837070 guards; pinned vendor files remain unchanged. Host execution does not qualify MCU exception priority, FP/MVE context switches, stack high-water or timing.

Running APIs require privileged, unmasked Thread mode. Before scheduler start, the pinned Baseline ports may retain PRIMASK=1 and Mainline ports their exact syscall BASEPRI; only that port’s canonical mask is permitted in that phase. Matching a value cannot identify its owner. Fault masks and other masks reject before object mutation; a read-only scheduler query distinguishes bootstrap from running/suspended tasks. Baseline IRQ wakes use the PRIMASK kernel contract; Mainline IRQ wakes validate implemented bounds, priority width and syscall ceiling.

Armv8-M supports explicit NTZ, Secure-only, and Nonsecure standalone build modes. The selected NTZ kernels do not allocate Secure task contexts or expose cross-world Secure function calls. Secure startup owns SAU/IDAU and Nonsecure coprocessor access; Nonsecure local masking cannot protect against Secure publishers. The default task APIs remain privileged; explicit MPU profiles provide a separate static restricted-task lifecycle and two pointer-free user delay/tick SVC services. Caller-owned protected metadata and reviewed user linker regions are required; no generic user-object pool or privileged I/O API is exposed. M0/M0+ and M7 MPU, and MPU combined with split security, are rejected. See the OS contracts and current matrix before selecting an optional isolation profile.

Explicit split mode instead selects the real TrustZone-aware Nonsecure ports and a separately linked Secure baremetal Runtime with Nexus::SecureContext. Both images use matching CPU/ABI facts and the actual CMSE import/SG veneers. Every authorized task, including Idle, has caller-owned NS TCB/stack and prepared Secure metadata/stack selected by an immutable trusted mapping. No Secure heap or maximum context pool is supplied. The NS privileged kernel is trusted; SAU/IDAU, startup, vectors, NSC memory attribution and interrupt routing remain consumer/SoC responsibilities. See the Secure companion contract before integration. Two-image linking and host lease tests do not qualify physical attribution, context retention, stack peaks or adversarial NS-kernel isolation.

The first scheduler start requires cold privileged Thread/MSP state with FPCA clear; applications must not leave active FP context before bootstrap. The MPU start guard consumes a protected single-use lease against the real origin/frame. For v8-M, authored security = "single" means Arch state 0, not Nonsecure. It uses the traditional FD/F9 port return tuple without CMSE permission; explicit Secure uses the same tuple with its separate Secure facts, while explicit Nonsecure uses BC/B8. The generated NEXUS_CPU_SECURE_ONLY macro selects that port encoding and does not grant Secure access to a single-world image.

M55/M85 use their actual MVE-aware exception/context ports. The kernel’s configENABLE_FPU switch activates the shared coprocessor register bank and extended/lazy exception frame for either FP or MVE; CPU scalar-FP facts remain independent. Integer-only MVE compiles with +nofp and softfp calling convention. Upper shared registers are saved by the port. Complete lower-bank and VPR retention depends on hardware extended exception framing and remains part of physical context-switch acceptance. This build contract does not qualify that behavior or guarantee cross-world payload preservation.

The host fixture keeps the pinned kernel and POSIX port unchanged, and uses tests/contracts/os_freertos_runtime/posix_event.c as its owned event support. The port cancels cond-waiting pthreads before signalling/joining them; upstream event support has no cancellation cleanup and can leave an exited thread’s mutex locked. Owned waits unlock on both return and cancellation, preventing repeated task-join deadlocks. This host-only correction does not change the MCU backend or establish MCU scheduler qualification.

Maintained execution contracts

See OS contracts, delivery scope and the OS01-OS55 execution ledger. New-kernel admission uses the backend integration contract and its active execution probe; a probe pass does not register another supported RTOS.

Finite notification deadlines are checked even after a coalesced sequence hint; continuous unrelated wakes cannot extend a wait. The public predicate receives one final observation after timeout, so an observed real completion can win. Queue operations keep immediate try semantics and consume an absolute budget only when blocking. NX_DEADLINE_NEVER uses genuine untimed host waiting.

Task creation validates the selected port’s startup frame and alignment before kernel mutation. Startup minimum and measured runtime stack budget remain distinct. One external lifecycle owner joins each returning task. Native tasks must not be cancelled or detached behind the adapter. Permanent tasks and direct notifications are explicit optional paths with their own storage and receiver/index contracts.

Closable queues use separate caller-owned controls and per-operation waiter storage; raw queues retain their minimal native blocking implementation. Shutdown must close admission, keep the owner progressing, settle and join producers, join the owner, quiesce hardware IRQ publishers and only then destroy notification, queue and guard storage. The external UART owner example demonstrates that flow.

The optional tickless path needs an explicitly bound timer port and a continuous clock; without it, normal Tick remains active. Diagnostics use caller-sized rings and weak no-op sinks. Trace, low power and task isolation do not imply physical qualification. tools/hil/os_acceptance.py prepares or verifies retained OS hardware records without operating equipment; all unexecuted physical cases stay not_executed.

Components

Optional common components

Explicit CMake targets compose narrow ports: bounded BusOwner, SPI/UART owner, BMP280 core and SPI transport, instance-level Log, two-bank commit-last Storage, physical Flash region and Native file adapters, and pure Modbus RTU parsing. Unreferenced component code does not enter a firmware image.

Owners have one executor, exact slot capacity, stable cancellation epochs and caller-owned operations. Initialization links unused slots before publication. Admission removes one free slot and appends one FIFO entry under the metadata guard; settlement/rejection returns one reusable slot. Both use constant work independent of capacity. The same slot link serves the free or FIFO chain, with one free-head index per owner and no extra per-slot storage. A slot reaching its final epoch is permanently retired, never rebound with a repeated identity. UART’s explicit inner provider request lets the owner release the outer request only after its last access. Devices and protocols do not choose Board pins, product registers, default workers or global lookup. Products supply transports, authorization, regions, task policy and budgets.

Meaningful regressions in tests/contracts cover concurrent producers, late cancel/TC, failure quarantine, interrupted persistence and protocol malformed inputs. A durable host file is not a physical Flash power-cut qualification.

Exact SoC implementations

The private implementation boundaries and reference configurations are maintained in STM32F407, GD32F470, STM32G474, STM32H743 and STM32U575. Their links bind this website revision.