驯服 Linux 抖动:PREEMPT_RT + Xenomai 实现 50µs 硬实时闭环控制
1. 挑战:在 30 美元的 SoC 上跑软 PLC
泰诺下一代运动控制器需要在单颗 SoC 上运行软 PLC 运行时,同时对六个伺服轴执行 20kHz 的闭环 PID 控制。目标硬件:售价约 30 美元的全志 A40i(四核 Cortex-A7)。没有 FPGA,没有专用 DSP——只有普通的 ARM 核跑 Linux。
问题显而易见:标准 Linux 即使配置了 SCHED_FIFO,在这类硬件上仍会出现 200~500µs 的调度抖动。对于周期仅 50µs 的 20kHz 控制环来说,这完全不可接受。错过截止时间意味着相位误差累积,最终导致机械系统失稳。
2. PREEMPT_RT 地基
第一步很直接:应用 PREEMPT_RT 补丁集,配置内核 CONFIG_PREEMPT_RT_FULL=y。这几乎将所有 Spinlock 临界区转换为可抢占的互斥锁,让内核实现近乎完全可抢占。
关键内核配置:
仅凭 PREEMPT_RT,最差调度延迟从 ~480µs 降至 ~80µs。有改善,但仍达不到 50µs 的预算。
3. 引入 Xenomai 4(EVL 核)
Xenomai 4 的 EVL 核与 Linux 并行运行一个独立的实时核心,在中断到达 Linux 内核之前就进行拦截。实时线程由 EVL 核直接调度,完全绕过 Linux 调度器。
我们在合成压力负载(hackbench + 以太网 IRQ 风暴 + 内存压力)下,使用 cyclictest 连续运行了 72 小时。测试结果:
| 配置 | 最小 | 平均 | 最大 |
|---|---|---|---|
| 原生 Linux 6.6 | 8µs | 52µs | 487µs |
| + PREEMPT_RT | 6µs | 18µs | 82µs |
| + PREEMPT_RT + Xenomai 4 | 2µs | 5µs | 31µs |
引入 Xenomai 后,72 小时内的最差延迟为 31µs——舒适地落在 50µs 预算之内。即使在所有四核满载 IRQ 负载的情况下,控制线程也从未错过 20kHz 的节拍。
4. 硬件选型考量
并非每颗 SoC 都适合实时场景。我们在最终选定 A40i 之前测试了三款候选:
- RK3399:算力强劲但电源门控激进——深度 C-states 引入约 200µs 的唤醒延迟,且无法可靠地抑制。
- i.MX6ULL:实时性极佳,但为单核 Cortex-A7,无法同时承载视觉 + 控制任务。
- A40i:四核,合理的时钟门控粒度,无电源门控空闲状态,主线 PREEMPT_RT 支持完善。
核心教训:选 SoC 优先看确定性唤醒行为,而不是峰值算力。一颗 2µs 能唤醒的慢核,远比偶尔需要 200µs 才能走出深度睡眠的快核更可靠。
5. 生产部署成果
运动控制器于 2026 年 Q2 出货。运行六个 20kHz PID 控制环,仅占用约 35% 的单核 Cortex-A7 算力——剩余余量足以驱动 PLC 运行时、Modbus TCP 网桥和基于 HTTP 的本地 HMI。相比上一代 FPGA+DSP 架构,物料成本降低约 60%。
达成这一目标的不仅仅是内核配置——而是三个层次的协同:面向硬件的 SoC 选型、PREEMPT_RT 处理软实时路径、Xenomai 承载硬实时控制线程。每一层各司其职,处理其最适合的延迟等级。