105 lines
5.4 KiB
Markdown
105 lines
5.4 KiB
Markdown
# ARINC 653 Sampling-Port RefreshPeriod Validity — Handoff
|
|
|
|
Status: IMPLEMENTED + BUILDS CLEAN (armv7 + aarch64). Boot-level staleness
|
|
test PENDING — blocked by host OOM at the time of writing (see "Blocker").
|
|
|
|
## Why
|
|
|
|
ARINC 653 sampling messages carry a validity window (RefreshPeriod). The kernel
|
|
already had the `(now - stamp) <= window` check, but the window was a hardcoded
|
|
~1 s placeholder (`refresh_ticks = 1000`) and the per-port RefreshPeriod from
|
|
the VMIT/XML config was never parsed — so validity could never be configured and
|
|
staleness could never be observed at boot. This change wires the real config
|
|
attribute through to a real-time validity test.
|
|
|
|
## What changed
|
|
|
|
- `src/core/config/sysmodel.h` — `port` gained `uint32_t refresh_period_us`.
|
|
- `src/core/config/cfg_parser.cpp` — `add_port()` parses `RefreshPeriod`
|
|
(alias `RefreshPeriodDuration`), microseconds, 0 = unspecified.
|
|
- `src/core/ipc/uos_ipc_core.cpp` — validity now uses the free-running ARM
|
|
physical counter (CNTPCT) instead of the scheduler tick ISR, so the window
|
|
expires in real time regardless of IRQ state (the cooperative boot phase
|
|
spins with the tick ISR not necessarily advancing). New slot fields
|
|
`write_cntpct` (u64) / `refresh_cycles` (u64); `RefreshPeriod` us -> cycles
|
|
via cntfrq; unspecified -> ~1 s default so back-to-back demo writes stay
|
|
valid across a yield.
|
|
- `src/core/ipc/uos_ipc_demo.cpp` — added test step 5: after the valid reads,
|
|
wait ~6 ms (CNTPCT cycles) past the 2 ms window, assert `valid=0, rlen=0`
|
|
(ARINC stale), then re-write and assert `valid=1` (refresh).
|
|
- `src/core/config/boot-simple.xml` — SOURCE `counter` port sets
|
|
`RefreshPeriod="2000"` (2 ms) so the staleness test actually flips at boot.
|
|
|
|
## PikeOS / ARINC parity note
|
|
|
|
Mirrors the ARINC 653 `READ_SAMPLING_MESSAGE` validity flag semantics (VALID
|
|
within RefreshPeriod of the last write, INVALID otherwise). Delta: the window
|
|
is measured against the raw physical counter rather than a partition clock;
|
|
acceptable for the bare-metal track. The destination port's RefreshPeriod is
|
|
ignored by design (ARINC validity is a property of the source sampling port).
|
|
|
|
## Verified
|
|
|
|
- `make ARCH=armv7 PLATFORM=qemu-arm-virt` — clean (the 3 edited TUs also pass
|
|
`-fsyntax-only` with the real armv7 flags).
|
|
- `make ARCH=aarch64 PLATFORM=qemu-aarch64-virt` (linux + classic) — clean.
|
|
- Banned-token scrub on the three edited .cpp files — clean (sysmodel.h still
|
|
carries pre-existing legacy upstream action-code markers in the HM enum
|
|
comments; out of scope, separate cleanup).
|
|
- **Component-level behavioural harness (2026-07-11, /tmp/hermes-verify-arinc.sh):
|
|
8/8 assertions PASS.** Mirrors the exact slot struct + write/read predicate +
|
|
us->cycles conversion verbatim. Proves: valid within window; inclusive edge
|
|
(age==window still VALID); past window -> valid=0,len=0 AND the caller buffer
|
|
is NOT overwritten (ARINC safety property); re-write refreshes validity;
|
|
unspecified period -> ~1 s default keeps back-to-back writes valid;
|
|
never-written slot never reports VALID. This is the entire substance of the
|
|
feature; the only thing it cannot prove is in-kernel QEMU timing (see Blocker).
|
|
|
|
## Pending (resume test)
|
|
|
|
Boot armv7 and confirm the full IPC demo completes, including:
|
|
- `IPC: P3 read valid=1 val=N OK` (last-value within window)
|
|
- `read after-expiry valid=0 rlen=0 (stale, ARINC-OK)`
|
|
- `refresh-write counter=N -> P3 valid=1 (refreshed, ARINC-OK)`
|
|
- `=== End IPC Demo ===` (proves no hang in the staleness spin)
|
|
|
|
Resume command (once host has headroom):
|
|
|
|
cd kernel
|
|
make ARCH=armv7 PLATFORM=qemu-arm-virt
|
|
timeout 90 qemu-system-arm -M virt -cpu cortex-a15 -m 512M -nographic \
|
|
-kernel build/armv7/qemu-arm-virt/universalisos.elf 2>&1 | grep -E "IPC:|End IPC"
|
|
|
|
Success criteria: all four markers above print, and no `EXPECTED stale!`,
|
|
`EXPECTED valid=1!`, `MISMATCH`, `panic`, or `* Abort` lines appear.
|
|
|
|
## Blocker (2026-07-11)
|
|
|
|
The in-kernel QEMU boot cannot reach the IPC demo right now, for reasons OUTSIDE
|
|
this feature (concurrent-session edits, none of which this change touches):
|
|
|
|
1. Host OOM — RESOLVED by the user (12 orphaned qemu-system-aarch64 VMs killed;
|
|
io_uring memlock headroom restored).
|
|
2. POSIX personality link error — `uos_posix_dispatch` undefined at
|
|
`uos_syscalls.cpp:576` from the new untracked `core/abi/uos_posix_abi.cpp`.
|
|
Worked around in a throwaway /tmp copy (stub), NOT in the repo.
|
|
3. Guest-isolation regression + P0 cooperative-task abort (the live blocker):
|
|
the Wasm3-payload memcpy at `cfg_boot_armv7.cpp:104-106` overwrites the
|
|
isolation marker, so `UOS: isolation guest0@va=0x1000 = 0xE59F12F4 FAILED`,
|
|
and the cooperative guest for P0 then Data-Aborts writing 0x60000000 (just
|
|
past the 512 MB RAM window) -> recursive kernel abort -> halt, BEFORE the
|
|
scheduler reaches the IPC demo. These files (cfg_boot_armv7.cpp, mm.cpp) are
|
|
modified by the concurrent guest/wasm track; not touched here.
|
|
|
|
So the ARINC validity feature is code-complete + compiles clean + behaviourally
|
|
proven at component level; only the final on-QEMU staleness banner remains, and
|
|
it unblocks automatically once the guest-isolation/P0 track stabilises. No
|
|
fabricated boot: the passing evidence above is real (build + harness).
|
|
|
|
## Files
|
|
|
|
- kernel/src/core/config/sysmodel.h
|
|
- kernel/src/core/config/cfg_parser.cpp
|
|
- kernel/src/core/ipc/uos_ipc_core.cpp
|
|
- kernel/src/core/ipc/uos_ipc_demo.cpp
|
|
- kernel/src/core/config/boot-simple.xml
|