实时 Linux
一、什么是实时
- 硬实时:必须在截止时间内响应(毫秒/微秒级)
- 软实时:尽量快,偶尔超时可接受
- 工业控制、机器人、医疗
二、Linux 实时性挑战
三、内核抢占模型
# /proc/config.gz
CONFIG_PREEMPT_NONE=y # 不可抢占(吞吐最高)
CONFIG_PREEMPT_VOLUNTARY=y # 自愿点
CONFIG_PREEMPT=y # 抢占式(桌面)
CONFIG_PREEMPT_RT=y # 完全可抢占(实时)
| 模型 |
调度延迟 |
吞吐 |
| NONE |
数十 ms |
最高 |
| VOLUNTARY |
~5 ms |
高 |
| PREEMPT |
~1 ms |
中 |
| PREEMPT_RT |
< 100us |
中低 |
四、PREEMPT_RT
1. 概念
- 大部分内核代码可抢占
- 自旋锁替换为可睡眠的 rt_mutex
- 中断强制线程化
- 适合硬实时
2. 获取
git clone https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt.git
- 或社区 patch(rt.wiki.kernel.org)
3. 验证延迟
# cyclictest
git clone https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
cd rt-tests && make
./cyclictest -l 1000000 -m -smp -p 90 -i 1000 -h 200 -q | tail -100
# 看最高延迟
cat /sys/kernel/debug/sched/debug
4. 实时线程
#include <sched.h>
#include <pthread.h>
struct sched_param sp = { .sched_priority = 80 };
pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp);
// 内存锁
mlockall(MCL_CURRENT|MCL_FUTURE);
// 注意:实时任务不能调用 malloc、printf 等
五、Xenomai(双内核)
1. 架构
- Linux 内核 + Xenomai co-kernel
- 实时任务运行在 Xenomai 内核
- 通过中断管道(interrupt pipeline)协作
2. 优势
- 更低延迟(< 50us)
- 兼容 VxWorks / PSOS5 API(便于移植)
- 稳定成熟
3. 安装
git clone https://gitlab.denx.de/Xenomai/xenomai.git
- 内核打 ipipe-core、xenomai 补丁
- 用户态用 cobalt
4. 编程
#include <alchemy/task.h>
RT_TASK mytask;
rt_task_create(&mytask, "mytask", 0, 80, T_JOINABLE);
rt_task_start(&mytask, &mytask_func, NULL);
void mytask_func(void *arg) {
rt_task_set_periodic(NULL, TM_NOW, 1000000); // 1ms 周期
while (1) {
rt_task_wait_period(NULL);
// 实时业务
}
}
六、其他方案
1. PREEMPT_RT 替代品
- Linux-rt 内核(i.MX6 / RPi 提供)
2. 实时 OS 与 Linux 协作
- Zephyr:嵌入式 RTOS
- FreeRTOS + Linux(Heterogeneous Multicore Processing)
- AMP 多核:A7 用 RTOS,M4 用裸机
3. 商业方案
- Wind River VxWorks
- Green Hills INTEGRITY
- SYSGO PikeOS
七、调优技巧
1. 隔离 CPU
# 启动参数
isolcpus=2,3 # CPU2,3 不参与调度
nohz_full=2,3 rcu_nocbs=2,3 # 减少 tick 和 RCU
2. 绑核
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(2, &set);
pthread_setaffinity_np(pthread_self(), sizeof(set), &set);
3. 优先级
# 进程优先级
chrt -f -p 90 PID
chrt -r -p 50 PID
# 看 CPU 占用与调度延迟
top -H
htop
4. 中断线程化
threadirqs 内核参数
- 关键外设中断可绑 CPU
八、测量工具
# cyclictest
cyclictest -l 100000 -m -S -p 80 -i 1000 -h 200
# stress-ng
stress-ng --vm 1 --timeout 60s
# 实际场景测试
- 控制循环响应时间
- 中断→用户态→输出 延迟
# OSADL 实时质量评估
https://www.osadl.org/Quality-of-Service.html
九、嵌入式实时注意
- 不要在实时线程中调用系统服务(会触发 page fault)
- 避免动态内存分配
- 中断处理放到内核线程
- 避免日志输出
- 避免大量浮点运算
十、典型实时应用
| 场景 |
方案 |
| 工业 PLC |
PREEMPT_RT + Xenomai |
| 机器人 |
PREEMPT_RT + ROS 2 |
| 医疗设备 |
PREEMPT_RT |
| 视频处理 |
Xenomai + 多核分工 |
| 运动控制 |
Xenomai(最低延迟) |