Deadline-Monotonic Scheduling of Control Tasks
Where several deterministic tasks share a core, priority follows deadline; a schedulability test proves the fastest safety task always meets its deadline.
Priority by deadline
The pure reflexes run on dedicated FPGA fabric, but the deterministic supervisory tasks — equilibrium updates, slower position loops, telemetry framing — share real-time cores. Kronos schedules these with deadline-monotonic priority: the task with the shortest relative deadline gets the highest priority. This is optimal for fixed-priority scheduling of periodic tasks with deadlines no greater than their periods.
Schedulability, not hope
A response-time analysis proves each task finishes before its deadline under worst-case interference from higher-priority tasks. A task set is admitted only if every task passes.
def response_time(i, C, T, D):
# C=WCETs, T=periods, D=deadlines; tasks sorted by deadline (i highest prio first)
R = C[i]
while True:
interference = sum(-(-R // T[j]) * C[j] for j in range(i)) # ceil()
R_new = C[i] + interference
if R_new == R:
return R <= D[i], R # schedulable if response <= deadline
if R_new > D[i]:
return False, R_new
R = R_new
Priority inheritance protects shared resources so a low-priority task holding a lock cannot indefinitely block a safety task — a classic priority-inversion hazard. On the reflex path proper, the problem is avoided entirely by allowing no shared resources at all.
- Highest priority: fastest protection loop (shortest deadline).
- Middle: position and shape loops at their derived periods.
- Lowest: non-safety telemetry and configuration tasks.
The analysis is redone whenever the task set changes, because adding even a light task raises the interference term for everything below it. Kronos treats the schedulability proof as part of the safety case, archived alongside the WCET evidence, so a reviewer can confirm that the shortest-deadline safety task still meets its deadline under the worst admissible load. Tasks that cannot be shown schedulable are moved to dedicated fabric rather than squeezed into a shared core.
If a proposed task set fails the test, the fix is architectural — move work off the shared core, not shave a WCET estimate. See WCET analysis for where the C values come from.