Explicit clock leases and shallow sleep¶
The current IO58 delivery provides static caller-owned clock admission, a drain barrier, and one shallow sleep under fixed STM32F407 / GD32F470 RUN configurations. The component creates no global PM registry, task, timer, maximum object pool or default state. Unselected Nexus::ClockDomain remains an EXCLUDE_FROM_ALL static target; sleep sources for both SoCs also require explicit optional-target references. Boards do not automatically select GPIO wake or alter electrical connections.
The public API uses opaque nx_clock_domain_t; mutable storage / constructors are private assembly details. The consumer supplies a naturally aligned, zero-initialized nx_clock_lease_t. Successful admission borrows the token’s identity and storage, with provider-managed fields; copying fields cannot release the original object. Each domain’s explicit capacity bounds alias and retained-identity scans; no capacity-independent constant time is promised.
The sole privileged Thread lifecycle owner calls close to prevent new leases, then drives each device’s stop and drains DMA/IRQ/completion notifications itself. Consumers release only after successful detach. Close does not cancel devices, and release does not prove a peripheral stopped. Timeout, close or sleep never revoke existing leases. quiescent succeeds only in the current closed epoch with both count and list empty. Reopen can monotonically advance the admission epoch only after drain; the maximum permanently rejects reuse. Old control values cannot reopen across epochs or establish drain proof. Domain storage outlives all control copies; resetting it with memset is prohibited.
Metadata saves/restores incoming PRIMASK; Native uses a real recursive thread-exclusion model. Acquire / release may run in same-CPU privileged Thread, PendSV, SysTick or external configurable IRQ; construction, close, quiescent and reopen require serialized privileged Thread. NMI, fault, SMP, signals and other security domains are outside the contract. Outputs and wake words cannot overlap private provider state, retained tokens or each other; rejection cannot corrupt already borrowed controls. There are no callbacks or accesses after token release.
SoC sleep runs in privileged Thread with incoming PRIMASK/BASEPRI/FAULTMASK all clear. Under the same saved mask it finally verifies the closed barrier, actual fixed register configuration and wake sequence, then enters production nx_arch_wait_for_interrupt. WFI preserves PRIMASK; an enabled IRQ becoming pending can wake it and runs after mask restoration. The owner must reread the actual business predicate after return. A changed sequence returns success with slept=false. Set SCR.SLEEPDEEP, STOP and dynamic RUN are explicitly rejected; SCR, RCC, Flash, Tick, pending IRQs and deadlines are never rewritten. A 32-bit wake sequence requires the caller to prove no complete wrap within the observation window; one snapshot does not solve DMA/NMI/SMP publication or unbounded ABA.
The verified STM32 profile is nominal HSE8 MHz / M8 / N336 / P2 / Q7, SYSCLK/AHB168, APB1 42, APB2 84 MHz, Flash5WS and SSCG disabled; GD is nominal HXTAL25 / M25 / N400 / P2 / Q9, SYSCLK/AHB200, APB1 50, APB2 100 MHz, Flash7WS, SSCG disabled and TIMERSEL=0. Sources are pinned SDK RCC/RCU/FMC register definitions and fixed startup values in current SoC system.c. GD main Q9 cannot claim USB48 MHz; the separate USB clock owner is responsible. Actual crystal frequency, supply, thermal drift and board layout cannot be measured through ready/divisor readback and still require physical qualification.
The owner must exclusively control RCC decisions, register all relevant consumers and provide an actually enabled wake IRQ; this module discovers no omitted consumers and never implicitly pauses a kernel. Actual deep STOP / PLL frequency-change extensions must first drain and stop all Tick/time providers, scheduler deadline borrowers and IRQs, then use an exclusive hardware port for bounded clock restore / rollback. New clock/time domains need cold reconstruction; old absolute deadlines cannot be inherited. This slice does not implement these extensions or disguise an admission epoch as time-domain conversion.
Google tests use the real production domain, real Native exclusion, both vendors’ actual SDK MMIO layouts and production Arch sleep, replacing only external CPU context / WFI leaves. Original link RED, actual SSCG/TIMERSEL/non-head-token failure regressions, GREEN, ASan/UBSan, strict ARM checks and identities are in tools/testing/evidence/clock-domain-iteration/manifest.json. These are not clean-release, whole-system zero-RAM/two-offline-build, physical HIL/WCET or power qualifications; later platform-integration/station evidence establishes those.
H743 SPI4 runtime pause and resume¶
For general static assembly and runtime access relationships, see the runtime access supplement.
The current IO-30 vertical slice selects one H743 revision V 0x2003 SPI4 finite-DMA controller with default HSI trim64, fixed HSI64 MHz, Cache off and baremetal. The maintained assembly tools/configure/assemblies/h743-spi-dma-runtime-clock.toml explicitly selects:
[power]
mode = "fixed-run"
controllers = ["bus4"]
The resolver rejects other controllers, endpoint aliases, empty or duplicate lists, unknown fields, other clock/cache configurations and OS backends. The selection emits one private domain and one lifecycle lease; assemblies without [power] have neither this state nor the runtime interfaces. The existing ClockDomain component remains the sole borrowing mechanism, with no new driver ops, public provider storage, background task or per-request forwarding layer.
The generated nx_platform_runtime_domain() returns only a static identity and does not initialize hardware. Platform startup acquires the lease before the first peripheral resource write. Even after acquire-observed request SETTLED, the initialized provider, IRQ, DMA, CS, pins and peripheral gates retain responsibilities, so the lease remains held. nx_platform_runtime_pause() closes admission and reuses the actual stop path; an active request returns BUSY, and the caller must continue actual cancel/service and retry. Release and quiescence are allowed only after proving DMA EN, address and mux withdrawal, owned IRQ withdrawal, wire completion, CS/SCK handoff, pin snapshot restoration and removal of owned gates. Refused address, CS, pin or gate restoration retains the lease and cleanup responsibility; zeroing memory never substitutes for stopping.
The sole lifecycle owner must first join submitters, controls and observers, then call pause/resume serially in privileged, unmasked Thread context. Closing the domain does not automatically prevent submission through an initialized endpoint, so this is not concurrent global suspend. nx_platform_runtime_resume() advances the admission epoch only after drain, then reacquires the lease and restores the original controller. A partial failure reports primary, cleanup and remaining-effects separately; the original responsibility can be completed only through actual pause or global stop. An old barrier cannot approve a new epoch.
Pause/resume preserves System and TIM2 CEN, prescaling and overflow ownership without changing the Core deadline domain. An original absolute deadline that expires during pause remains expired after resume. Global nx_platform_stop() remains a separate all-consumer stop path; it cannot replace runtime pause or preserve deadlines across its restart. This slice changes neither PLL, supply, Flash latency nor kernel Tick. It does not implement WFI, deep STOP, DVFS, GPIO sleep/wake electrical policy or clock capabilities for other boards.
The new Google program connects the same normally generated assembly to the actual H743 System/SPI/GPIO/DMA/ClockDomain providers and external MMIO/IRQ models. It checks leases retained across SETTLED, pending RX commits, failure retries, actual gate and pin withdrawal, and pending TIM2 wrap during pause. Software model and subsequent Debug/ASan results do not establish MCU execution, power, WCET, clean SDK or physical HIL qualification; the complete IO-30 exit conditions remain to be verified.