OS delivery scope and verification

The OS retains public Wait plus backend-specific explicit storage. The platform creates no default workers, starts no scheduler, implicitly occupies no task-notification index and creates no maximum object pools. Product composition/recovery policy live in independent examples/product projects.

Full contracts are in OS contracts; per-item actual status is in OS01–OS55 ledger. implemented means code exists. Software qualification requires actual execution bound to current clean Git/config/dependency/tool identities.

Mechanism

Delivery boundary

Wait

One waiter, multiple legal publishers, absolute same-domain deadlines and authoritative business predicates

Baremetal

Bounded polling without task emulation; sleep uses explicit Arch contracts

Native

Caller stacks, join, closable byte-copy queues and real monotonic condition waits

FreeRTOS

Maintained nine-core ports, static objects, legal task/IRQ contexts and joinable lifecycle

direct notify

Explicit receiver/index/lifecycle reduce optional binary-semaphore costs

permanent task

No join semaphore; entry never returns and storage remains until reset

closable queue

Separate opt-in storage/waiters; raw queues pay no default close cost

Tick/profile

SoC IRQ/CPU facts separate from runtime policy; explicit legal Tick sources

low power

Shallow sleep plus explicit timer port; no automatic sleep without a port

trace

Caller bounded ring plus weak hook; no default large trace buffer

MPU

Separate restricted-task profile, protected metadata, explicit user linker/regions and narrow delay/tick SVC

split security

Matched Secure/NS Runtime, actual TZ-aware port, caller Secure contexts and Idle storage

External application delivery

nexus-examples/apps/uart_owner_runtime uses generated typed-factory UART faces. Native creates actual pthreads for two producers/one owner. FreeRTOS creates explicit static producer/owner/stop-coordinator tasks. Baremetal cooperatively services the same owner. Three Boards reuse existing console routes without defining new wiring/providers.

Shutdown includes admission stop, active cancel/drain, producer join, owner join, IRQ-wake quiescence and notification destruction. GoogleTest/GoogleMock exercise actual BusOwner/application-shutdown modules, mocking only external join/hardware quiescence. Coverage includes stage order, timeout, errors, premature reclaim and retries.

Partial startup failures reclaim acquired resources separately. Native closes submission, keeps the owner draining and joins running tasks. Pre-scheduler FreeRTOS uses nx_freertos_task_discard_before_scheduler: suspend removes kernel candidate-TCB references before synchronous task/completion-latch deletion. It requires privileged bootstrap, NOT_STARTED, an unexecuted wrapper and no unmatched scheduler suspension. Successful discard alone permits stack/TCB/context reuse; running tasks use cooperative stop/join. Actual POSIX-kernel regressions verify reverse reclaim, poisoned-storage reuse, actual scheduler execution and refusal to discard executed wrappers after scheduler end; they replace no MCU validation.

Native explicitly provides three 64 KiB host-stack buffers, separately increasing application budgets; this is host-fixture cost, not MCU stacks. MCU references use four tasks of 256 StackType_t words each with 8-byte alignment; physical peak measurement remains required and is not inferred from startup minimums. After I/O/publisher stop, FreeRTOS retains scheduler clock/Tick and suspends the coordinator. Native/baremetal may continue platform stop. Products separately own reset/scheduler-stop policy.

Software verification and physical boundaries

Software execution should cover continuously waking deadlines, final-completion races, startup-stack rejection, complete Baseline IRQ binding, close/drain, task reuse, direct-notification receiver/index, tickless failures and trace overflow. GoogleMock context models, actual POSIX kernel, Native multitasking, nine-core ABI links and installed SDK consumption each establish separate evidence.

Twelve actual ARM MPU variants and V7/V8 host contracts were executed; M0/M0+, M7-kernel-MPU and MPU+split are rejected. Optional split has 31 Secure/NS pairs (62 ELFs), covering maintained M23/M33/M55/M85 CPU-authority combinations and checking seven real SG veneers/imports/context ASM/caller Idle callbacks without default Secure heaps/pools. Two host lease targets cover integer/shared-FP-MVE-bank software contracts. Both require explicit consumer linkers/storage/trusted lifecycles. Fixture addresses are synthetic; actual MPU faults, security attribution, cross-world startup/context switches remain unexecuted. See OS contracts.

OS49–55 physical fixtures execute as prepare/validate tools, but disconnected hardware means no actual IRQ→task latency, FP/MVE retention, MSP/task peaks, Tick/deadline error, full-load lifecycle, sleep recovery or exception-safe outputs. Plans remain prepared_unbound, physical status not_executed. Plans are not measurements, WCET, safety certification or product releases.

python tools/hil/os_acceptance.py plan \
    --resolved build/stm32-qiming-freertos/generated/resolved.json \
    --report build/stm32-qiming-freertos/os-hil-plan.json

After hardware connection, station owners set five budgets: os_irq_latency, os_deadline_lateness, os_low_power_lateness, os_lifecycle, os_fail_response, with us/us/us/count/us units. Lifecycle requires positive minimum; the other four use maximum. Records bind station admission and budgets cannot be relaxed inside acquisition context.

Strict OS-context fields are schema_version=1/kind=os_hil_context, admission_sha256, workload/instrument file identities, actual load/executor/irq_priorities/cpu_clock_hz, features.fpu/mve, complete stack_names and requirements. Names include MSP/every selected workload task and raw stack traces must match exactly, not one example task. Features exactly match admitted CPU ABI. Each independent raw trace binds context SHA and retains per-sample/register/stack/lifecycle/fail-stop data. A self-authored status=passed summary cannot replace it. Acquisition time needs a fresh UTC offset.

python tools/hil/os_acceptance.py validate \
    --admission station/admission.json \
    --raw-evidence station/os-run.json \
    --report station/os-validation.json

Reports require unused output targets and never overwrite old evidence/inputs. These commands read retained records only and never operate hardware automatically. Actual station/workload review owns measurement method, observed load, power, safe outputs and product budgets; host models/old commits confer no physical qualification.

Explicit optimization costs

The 32-bit-ABI standard development resource probe measured the object sizes below. Changed profile/CPU port/enum ABI/compiler requires fresh cost gates. These are actual ELF object sizes, not runtime cycles/final software-candidate qualification.

Object

RAM bytes

Cost responsibility

Wait face

16

Retains existing public ABI

Ordinary notification

84

Per-object static latch

direct notify

16

Explicit receiver/index; saves 68 B

Joinable task

172

Excludes caller stack

Permanent task

88

Excludes caller stack; saves 84 B

raw queue

80

Excludes payload

closable queue

96

16 B above raw; excludes payload/waiters

Each concurrent queue waiter

84

Caller provides actual concurrency capacity

Idle TCB plus default stack

596

Default 84+512 B; profiles may change it

maximum_waiters bounds close traversal while the scheduler is paused; payload item size bounds each kernel-copy critical section. Entire close traversal is not IRQ-masked time and static instruction counts are not measured latency. Cost gates retain argv, ELF/nm/disassembly/sizes. Compare minimal-resource/complete-capability profiles separately; different-workload images are not one baseline.