- HARD_REALTIME_EVALUATION.md: full HRT audit - MICROKERNEL_*.md: complete architecture targets and implementation plan - PIKEOS_3LAYER_REPLICATION_PLAN.md: 3-layer replication strategy - PIKEOS_POSIX_AUDIT.md: POSIX compliance audit - RTOS_AUDIT.md: RTOS comparison - XTENSA_AUDIT.md: Xtensa ISA audit - BIBLIOGRAPHY_SAFETY_CRITICAL_HYPERVISOR.md: references
8.2 KiB
UniversalisOS — Hard Real-Time Re-Evaluation
The Brutal Truth
We built a cute microkernel that boots, runs tasks, has semaphores and mutexes, and compiles for 12 targets. But if you put it in a hard real-time system today, it would miss deadlines and kill people.
This document re-evaluates every component against hard real-time requirements and defines what must change to achieve certifiable hard real-time.
1. What "Hard Real-Time" Actually Means
Hard real-time is NOT "fast". It is deterministic and bounded:
| Requirement | Meaning | Failure Mode |
|---|---|---|
| Bounded ISR latency | Worst-case interrupt-to-handler time is provable | Missed deadline → catastrophic |
| O(1) scheduling | Context switch time independent of task count | Jitter → missed deadline |
| Bounded critical sections | Interrupt-disabled time has a provable upper bound | Extended latency → deadline miss |
| Priority inheritance | Low-priority task can't block high-priority indefinitely | Priority inversion → deadline miss |
| No unbounded allocation | Memory is static, no fragmentation possible | Allocation failure → crash |
| WCET analysis | Every code path has a measured worst-case time | Unanalyzable → uncertifiable |
| Temporal isolation | Tasks can't steal each other's CPU time | Interference → cascade failure |
| Spatial isolation | Tasks can't corrupt each other's memory | Corruption → crash |
| Stack monitoring | Overflow detected BEFORE corruption | Silent corruption → crash |
2. Current Deficiencies (Honest Audit)
🔴 CRITICAL — Will Miss Deadlines
2.1 Tick Handler is O(N) — uos_tick.c:21
for (uint32_t i = 0; i < UOS_MAX_TASKS; i++) { // ← LINEAR SCAN
uos_task_t* t = &g_task_pool[i];
if (t->state == UOS_TASK_BLOCKED && t->delay_until != 0) { ... }
}
Problem: The SysTick ISR iterates ALL tasks every tick. With 16 tasks at 1kHz, that's 16,000 iterations/second inside an interrupt. The ISR execution time grows linearly with task count. This is unacceptable for hard RT.
Fix: Use a delta-list (timer wheel) — sorted by expiry time. ISR only checks the head. O(1) for the common case.
2.2 No Interrupt Latency Guarantee
Problem: Critical sections use cpsid i (global interrupt disable).
There is no bound on how long interrupts stay disabled. The mutex and semaphore
code disable interrupts during the entire blocking operation path.
Fix: Use short, bounded critical sections. Never hold cpsid i
across a context switch or blocking call. Use PRIMASK save/restore with
a maximum-disable-time assertion.
2.3 Priority Inheritance is Incomplete — uos_mutex.c
Problem: The mutex boosts the owner's priority when a waiter blocks,
but mutex_pi_restore() is a no-op — it never restores the original
priority when the mutex is released. This means:
- Priority stays artificially high forever
- Medium-priority tasks starve
- The "inheritance" is actually a permanent promotion
Fix: Store orig_prio in the mutex (not just the task).
On unlock, restore from the mutex's own field.
2.4 No Stack Overflow Detection
Problem: Stack overflow corrupts adjacent memory silently. No canary, no guard page, no MPU region check.
Fix: Stack canary at stack base (pattern fill + check on context switch). On MPU targets: MPU region with no-access guard page below each stack.
2.5 No Timer Service
Problem: The API declares uos_timer_t but there is no implementation.
Software timers (one-shot and periodic) are essential for hard RT.
Fix: Delta-list timer service driven by the tick handler.
🟡 SERIOUS — Must Fix for Certification
2.6 No Deadline Monitoring
Problem: No mechanism to detect if a task exceeds its WCET. AUTOSAR has timing protection. APEX has HM. We have nothing.
Fix: Per-task execution budget. Reset on activation. If budget exhausted → ProtectionHook → configurable action.
2.7 No Preemption Threshold
Problem: Every ready task with higher priority preempts. With 32 priority levels and many tasks, this causes unnecessary context switches.
Fix: Preemption threshold (ThreadX pattern) — task specifies minimum priority that can preempt it.
2.8 No ISR Latency Measurement
Problem: We can't prove worst-case interrupt latency. DO-178C / ISO 26262 require evidence.
Fix: Instrument every ISR entry/exit with cycle counter. Store min/max latency. Provide API to retrieve.
2.9 Scheduler Not Tickless-Capable
Problem: SysTick fires at fixed 1kHz regardless of workload. Tickless idle reduces power and jitter.
Fix: When idle, calculate next wake time, reprogram SysTick to skip ticks. Standard FreeRTOS/RTX pattern.
2.10 No Cache Analysis Support
Problem: On Cortex-M4/M7 with cache, cache misses add unpredictable latency. Hard RT requires cache analysis or locking.
Fix: Optional cache locking API. WCET analysis considers cache state.
🟢 GOOD — Already Hard-RT Compatible
- O(1) bitmap scheduler —
sched_highest_prio()uses CLZ, constant time ✓ - Static allocation — No malloc, no fragmentation ✓
- Priority bitmap — Ready-queue lookup is O(1) ✓
- No virtual memory — No page fault latency ✓
- Freestanding — No libc dependencies ✓
- Preemptive — PendSV context switch works ✓
3. The Hard Real-Time Roadmap
Phase HRT-1: Fix the Critical Violations (1-2 weeks)
| Item | What | Impact |
|---|---|---|
| HRT-1.1 | Delta-list timer wheel | O(1) tick handler |
| HRT-1.2 | Bounded critical sections | Provable ISR latency |
| HRT-1.3 | Complete priority inheritance | No priority inversion |
| HRT-1.4 | Stack canary + overflow check | Corruption prevention |
| HRT-1.5 | Software timer service | Periodic task support |
Phase HRT-2: Certification Hooks (2-3 weeks)
| Item | What | Impact |
|---|---|---|
| HRT-2.1 | Execution budget monitoring | WCET enforcement |
| HRT-2.2 | ISR latency instrumentation | Measurable worst-case |
| HRT-2.3 | Preemption threshold | Reduced context switches |
| HRT-2.4 | Stack high-water mark | Stack sizing evidence |
| HRT-2.5 | Deadline monitoring | Deadline miss detection |
Phase HRT-3: Advanced Hard RT (3-4 weeks)
| Item | What | Impact |
|---|---|---|
| HRT-3.1 | Tickless idle | Power + jitter reduction |
| HRT-3.2 | Static schedule tables | Time-triggered scheduling |
| HRT-3.3 | Dual-core lockstep | Cortex-R safety |
| HRT-3.4 | Cache locking API | Deterministic memory access |
| HRT-3.5 | Formal verification hooks | seL4-style proofs |
Phase HRT-4: Certifiability (ongoing)
| Item | What | Impact |
|---|---|---|
| HRT-4.1 | WCET trace generation | DO-178C / ISO 26262 evidence |
| HRT-4.2 | MC/DC test coverage | DO-178C Level A |
| HRT-4.3 | Requirements traceability | Certification artifact chain |
| HRT-4.4 | Code coverage analysis | 100% MC/DC on safety-critical paths |
4. What This Changes About the Vision
What stays the same:
- Universal
uos_*API across all architectures ✓ - Personality shells (FreeRTOS, APEX, AUTOSAR, Mbed OS) ✓
- 12+ hardware targets ✓
- Tier 0/1/2/3 architecture tiers ✓
What changes:
- Priority order shifts: Hard RT correctness > feature count > target count
- Every new feature must prove bounded execution time before merging
- No blocking operations inside ISRs — ever
- No unbounded loops in kernel code — ever
- All critical sections must have measured maximum duration
- Memory must be 100% static — no dynamic allocation after init
- Every API must have a documented worst-case execution time
The new rule:
A feature is not "done" until its worst-case execution time is bounded and measured. If you can't bound it, it doesn't ship.
5. Re-Prioritized Implementation Order
NOW: HRT-1: Fix critical violations (delta-list, PI fix, stack canary)
NEXT: HRT-2: Certification hooks (budget monitoring, ISR latency)
THEN: Personality shells get hard-RT audit (FreeRTOS/APEX/AUTOSAR)
AFTER: HRT-3: Advanced (tickless, schedule tables, cache locking)
LATER: More targets (but each must pass HRT audit)
The personality shells are already built. The hardware ports work. The gap is determinism. That's what we fix now.