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.
The physical layout groups Arm CPU implementations by ISA and MCU packages by vendor. Family identifiers, public include paths and explicit target names remain stable. These are source ownership groups, not runtime forwarding layers.
Historical development collections are retained in the evidence archive with exact member identities and restore instructions. Their original source and execution scope remain unchanged; archive restoration does not establish current-source qualification.
arch/
include/nexus/arch/ public CPU contracts
arm/cortex_m/ selected Arm Cortex-M implementation
native/ host CPU primitives
drivers/
<kind>/<ip>/ reviewed reusable register-protocol algorithms
soc/
common/ cross-vendor SoC collaboration contracts
native/configure/ Native policy and static emission
native/drivers/ independent host device models
stm32/common/ STM32 identity helpers
stm32/<family>/ maintained STM32 provider packages
configure/ STM32 family policy, construction and emission
gd32/<family>/ maintained GD32 provider packages
configure/ GD32 family policy, construction and emission
tools/configure/
providers/ explicit provider map and shared leaf contracts
tests/providers/<family>/ host configuration tests
io/
include/nexus/io/ public I/O contracts
src/api/ checked face dispatch
src/mechanisms/ shared bounded I/O rules
src/controllers/ shared selected controller engines
private/ private structures and hardware ports
components/
<component>/ common mechanisms
soc/stm32/<extension>/ explicitly selected STM32 extensions
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¶
Public headers remain in include/nexus/arch/. Arm Cortex-M implementation
sources live in arm/cortex_m/, and host primitives live in native/. The ISA
directory is a build-time ownership boundary; CPU facts select one implementation
without a runtime CPU factory. A new architecture needs its own reviewed
implementation and compiler contract rather than a placeholder support claim.
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.
The pinned official CMSIS-Core v6.4.0 headers
core_cm0plus.h, core_cm7.h, core_cm23.h, core_cm33.h,
core_cm55.h, core_cm85.h, m-profile/armv7m_mpu.h,
m-profile/armv8m_mpu.h and m-profile/armv7m_cachel1.h provide reviewed
register-layout references. The shared private Core source does not
change Nexus’s public context, ownership, mask-restoration or cache/MPU/SAU
contracts, and does not establish new processor/profile or physical support. Actual IRQ latency,
privilege transitions, DMA/cache coherency and CPU timing require HIL.
Typed I/O¶
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.
The common public abstraction is the wait/wake port. Task, queue, join and storage APIs are deliberately backend-specific and expose the selected kernel’s real control-block requirements. A product switching kernels adapts its task lifecycle explicitly; the platform supplies no universal Task/Queue ABI or maximum storage pool.
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, TMP117 one-shot I2C, instance-level Log, two-bank commit-last Storage, physical Flash region and Native file adapters, bounded Settings/KV staging, and pure Modbus RTU parsing. Unreferenced component code does not enter a firmware image.
Nexus::Settings builds on Storage with caller-owned staging, product-assigned
integer keys and an explicit schema/capacity. Only commit writes persistent
storage; schema migration, defaults, authorization and Flash regions remain
external. See the component contract and the
development workflow.
General mechanisms remain in their named component directories. Exact STM32
extensions live under components/soc/stm32/, including selected F407 handoff/I2S2
and U575 retained-time/LPDMA/Stop2 mechanisms. Their public include paths and
explicit target names stay stable. This source grouping does not broaden the supported
chip, backend, clock, security or physical qualification scope.
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.
Selected network and boot contracts¶
The network component contract owns adapter execution, copied TCP bytes, TX outcome observation and shutdown. The selected RX payload-loan contract owns the optional copied/loaned stack profiles and the separate public/Storage target boundaries. Final pbuf free marks a loan ready; the serialized owner later releases the exact MAC loan. Stop retains storage while references or failed releases remain. These choices do not qualify PHY wiring, DMA/cache or HIL.
The MCUboot component contract owns the selected overwrite-only profile, explicit Flash composition, the boot/application ownership diagram and product recovery duties. The public control API renders only the generic C11 header. Concrete Flash-port types and private boot/profile headers remain outside that API surface. Model and linked-image evidence do not establish power-cut recovery or physical Flash qualification.
Exact SoC implementations¶
SoC packages and private providers¶
MCU source ownership follows the vendor and exact maintained family. Public
family identifiers such as stm32f407 and gd32f470 remain unchanged. The
maintained family descriptor supplies the canonical source directory; directory
names do not create another configuration authority or a runtime registry.
soc/
common/ cross-vendor SoC collaboration contracts
native/
configure/ Native provider policy and static emission
drivers/ independent host models
stm32/
common/ STM32 identity helpers
stm32f103/ stm32f407/ stm32g474/ stm32h743/ stm32u575/
gd32/
gd32f303/ gd32f470/
Each MCU family owns soc.json, routes.json, its private controller state,
selected driver sources and explicit CMake targets. Its configure/ package owns
family capabilities, admission, construction and lifecycle emission. Provider
tests remain in tools/configure/tests/providers/<family>/; shared parsing,
typed IR, resource arbitration and bundle transactions remain in tools/configure/.
Startup, clocks, timebase, memory and power code remain with that family.
Reusable IP algorithms live in drivers and are
shared only after every wrapper checks the real vendor layout, bits, clocks,
IRQ/DMA routes and errata. Similar peripheral names do not establish equivalence.
native/drivers/ implements the public I/O contracts as independent host models;
it does not establish MCU timing or electrical behavior. common/uart_control.h
is a cross-vendor SoC collaboration contract; STM32 identity access belongs in
stm32/common/stm32_identity.h. Neither is a reusable peripheral algorithm.
The Board packages authorize reviewed PCB bindings. Adding a Board does not enable a new clock tree automatically: select an exact maintained clock profile, or implement and verify another profile. Keep unsupported oscillators, domains, modes and silicon revisions explicit.
Use the provider guide for implementation,
the derived matrix for selected routes and
modes, and the qualification guide
for actual evidence. CPU support, SDK macros and source-directory presence do
not establish whole-family support. MCU physical HIL remains not_executed.
Reusable IP implementations¶
Reusable IP implementations¶
This private source directory groups reviewed register-protocol algorithms by
controller kind and IP implementation. A selected SoC target compiles the required
sources directly with private includes and its exact ABI. Public faces and
request ownership remain in io/; chip clocks, routes, startup, memory and
provider state remain with the exact SoC. This grouping adds no runtime layer,
registry, allocation, queue or worker.
Source directory |
Maintained algorithm |
|---|---|
|
Legacy USART with fixed-channel DMA |
|
Reviewed V1 IRQ/DMA message sequencing |
|
Reviewed V2 polling message sequencing |
|
Legacy single-shot ADC |
|
Legacy fixed PWM |
|
Legacy halfword Flash programming |
The I2C V1 engine is shared by STM32F407, GD32F470, STM32F103 and GD32F303. The first pair retains its reviewed 100 kHz profile. The 8 MHz low-end pair uses nominal 80 kHz, priority-zero non-kernel IRQs and no I2C DMA. ES096 2.8.1/2.8.5 and GD32F30x limitations 2.8.1 require these narrower choices. The F4 stream-DMA layout is never reused for a fixed-channel controller. Captured wake publishers join before stop returns borrowed notification storage; a refused vector withdrawal retains the initialized owner for explicit retry. Each SoC wrapper verifies its actual SDK register offsets and bit definitions, supplies exact clock, DMA/IRQ and visible-memory facts, and binds the selected static state. Matching register names cannot establish another chip’s routing, pin wiring, clock rate or errata policy.
The UART V1 channel-DMA engine is shared by the exact F103 and GD303 providers.
Its wrappers assert legacy USART and fixed-channel DMA masks and layout.
dma-tx owns one TX channel and an explicit IRQ byte ring; dma-duplex owns
both channels and caller-provided finite RX blocks. Actual wire TC remains
independent of DMA memory completion. The engine detaches each source, observes
a stable remaining count and acknowledges flags before returning a buffer.
Unprovable withdrawal retains the request or producer loan. Normal RX restarts
through owner service, with explicit gaps and backpressure; no consumer block
is overwritten. A byte discarded from DATA at a finite boundary records loss.
Neither circular reception nor a cache contract is inferred from this engine.
Keep per-byte operations shared only when their hardware protocol is identical.
Cold validation, NVIC withdrawal and chip resources stay in SoC wrappers.
A differing protocol or erratum requires a reviewed implementation or explicit
narrow capability; do not add speculative family switches to a shared hot path.
STM32 identity access remains in soc/stm32/common/stm32_identity.h and the
cross-vendor SoC control contract remains in soc/common/uart_control.h.
CMake remains the only source graph. Unselected algorithms must not compile merely because their files exist here. Review the actual linked retention and resource costs of selected sources. Register-boundary models exercise the real engine and wrappers, including rejection, errors, cancel, failed drain and instance isolation. Compile each selected ARM implementation separately. Native models and linked ARM images establish different software properties; timing and electrical claims still require physical execution. See execution budgets and the provider guide.
The private implementation boundaries and reference configurations are maintained in STM32F103, GD32F303, STM32F407, GD32F470, STM32G474, STM32H743 and STM32U575. Their links bind this website revision.
Board packages¶
Reviewed Board facts¶
A Board package records PCB/source identity, the exact SoC, oscillators, reviewed controller bindings, safe initial levels, reserved resources, provenance and explicitly unknown electrical facts. It reuses the selected SoC provider; it does not copy drivers or vendor SDKs.
boards/<board>/
board.json reviewed facts and permitted bindings
README.md source, connector and qualification limits
Private PCB packages belong in external product repositories and are selected
through board_package. Maintained public packages are selected through board.
Keep the family identifier independent of the manufacturer’s physical directory.
Board declarations cannot change a chip’s memory geometry or enable an
unmaintained clock profile, DMA route or controller mode.
Start with an exact part and a small reviewed route set, then follow the
Board porting guide. A syntactically valid JSON
file does not establish fitted components, connector continuity, power supply
or physical timing. Uninspected PCB revisions and jumpers remain unknown;
software fixtures do not qualify a real PCB. MCU physical HIL remains
not_executed.