Real-Time OS (RTOS)
[!NOTE] This module explores the core principles of Real-Time OS (RTOS), deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.
1. Determinism Over Throughput
In a standard OS (Windows, Linux), the goal is Throughput: Get as much work done as possible. If a video frame drops, it’s annoying, but nobody dies.
In an RTOS (VxWorks, FreeRTOS), the goal is Determinism: Guarantee a response within a strict deadline. If an airbag deploys 10ms late, the driver dies.
Hard vs Soft Real-Time
- Hard Real-Time: Missing a deadline is a system failure.
- Examples: Anti-lock brakes, Pacemakers, Nuclear Reactor control.
- Soft Real-Time: Missing a deadline degrades quality but the system survives.
- Examples: VoIP calls, Video streaming, Online gaming.
2. Real-Time Scheduling Algorithms
How do we guarantee deadlines?
Rate Monotonic Scheduling (RMS)
- Static Priority: Assign fixed priorities based on period (frequency).
- Shorter Period = Higher Priority.
- Optimal: For fixed-priority algorithms. If a set of tasks cannot be scheduled by RMS, no other fixed-priority algorithm can schedule them.
Earliest Deadline First (EDF)
- Dynamic Priority: Assign priority based on absolute deadline.
- Closest Deadline = Highest Priority.
- Optimal: Can achieve 100% CPU utilization (RMS is limited to ~69%).
- Risk: If overloaded, it fails unpredictably (Domino Effect).
3. Interactive: Scheduler Arena (RMS)
See how fixed priorities work. Task A runs every 4s (High Prio). Task B runs every 8s (Low Prio).
4. The Priority Inversion Problem
This is the most famous bug in RTOS history (Mars Pathfinder, 1997).
Scenario:
- Low Priority Task (L) grabs a mutex (Lock M).
- High Priority Task (H) wakes up and needs Lock M. It blocks.
- Medium Priority Task (M) wakes up. Since
Prio(M) > Prio(L), M preempts L. - Result: L cannot run (preempted by M), so it cannot release the lock. H is blocked waiting for L. effectively, Medium Priority M is blocking High Priority H!
Solution: Priority Inheritance Protocol
When H blocks on a lock held by L, L temporarily inherits H’s high priority. This prevents M from preempting L. L finishes, releases the lock, and drops back to low priority. H grabs the lock and runs.
5. Code Example: Real-Time Threads
Standard OS threads are not real-time. But we can simulate the priority logic.
package main
import (
"fmt"
"time"
)
// Simulating a Periodic Task Loop
func periodicTask(name string, period time.Duration, cost time.Duration) {
ticker := time.NewTicker(period)
for t := range ticker.C {
start := t
deadline := start.Add(period)
fmt.Printf("[%s] Start at %s (Deadline: %s)\n", name,
start.Format("05.000"), deadline.Format("05.000"))
// Simulate CPU Work
time.Sleep(cost)
now := time.Now()
if now.After(deadline) {
fmt.Printf("⚠️ [%s] MISSED DEADLINE by %s!\n", name, now.Sub(deadline))
} else {
fmt.Printf("✅ [%s] Finished. Slack: %s\n", name, deadline.Sub(now))
}
}
}
func main() {
// Task A: Period 1s, Cost 200ms
go periodicTask("Safety", 1*time.Second, 200*time.Millisecond)
// Task B: Period 3s, Cost 1s
go periodicTask("Logger", 3*time.Second, 1*time.Second)
select {} // Block forever
}
// Java has a Real-Time Specification (RTSJ)
// But standard Java threads rely on the OS scheduler.
// We can set priorities, but they are just "hints" to Linux.
public class RealTimeSim {
public static void main(String[] args) {
Thread high = new Thread(new Task(200), "SafetyCheck");
Thread low = new Thread(new Task(1000), "DataLogging");
// 10 is Max, 1 is Min
high.setPriority(Thread.MAX_PRIORITY); // 10
low.setPriority(Thread.MIN_PRIORITY); // 1
low.start();
high.start();
}
static class Task implements Runnable {
int costMs;
public Task(int c) { this.costMs = c; }
public void run() {
while(true) {
long start = System.currentTimeMillis();
// Simulate work
while(System.currentTimeMillis() - start < costMs) {
// spin
}
System.out.println(Thread.currentThread().getName() + " Done");
try { Thread.sleep(1000); } catch (Exception e) {}
}
}
}
}
6. Summary
- Determinism: The guarantee that X will happen by time T.
- RMS: Optimal fixed-priority (Rate Monotonic).
- Priority Inversion: A lower priority task blocking a higher priority one. Solved by Inheritance.