第二章:Linux内核实时性改造

好,咱们进入第二章。这一章可以说是整个实验平台的基石——把树莓派的内核改造成实时内核。说白了,就是让Linux能“准时”干活。

我刚开始接触实时系统时,总觉得普通Linux挺快的啊,为什么还要折腾?直到有一次做电机控制项目,发现任务响应时间忽长忽短,最差情况差了十几毫秒。嗯,那一刻我才明白——普通Linux的“快”是平均快,但实时系统要的是“最差情况也快”。

2.1 内核源码下载

首先,得拿到树莓派的内核源码。树莓派官方维护了一个分支,叫rpi-开头的版本。我个人习惯用rpi-6.1.y这个分支,比较稳定。

下载命令很简单:

# 在树莓派上直接操作
git clone --depth=1 --branch rpi-6.1.y https://github.com/raspberrypi/linux.git
cd linux

这里我用了--depth=1,只拉取最新代码。为什么?因为完整的历史记录太大了,树莓派的SD卡空间有限。你想想看,一个完整仓库几个G,我们只需要编译一次,没必要。

我的小技巧: 如果你在PC上交叉编译,记得用--depth=1参数。我曾经因为没加这个参数,下载等了半小时,SD卡还差点爆了。

2.2 PREEMPT_RT补丁打补丁

接下来是关键步骤——打上PREEMPT_RT补丁。这个补丁是Linux实时性的灵魂。

补丁版本必须和内核版本严格匹配。比如内核是6.1.66,补丁就得是patch-6.1.66-rt30.patch这种。版本号差一位都不行,我踩过这个坑。

# 下载对应补丁
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.1/patch-6.1.66-rt30.patch.xz
xz -d patch-6.1.66-rt30.patch.xz

# 打补丁
cd linux
patch -p1 < ../patch-6.1.66-rt30.patch

打补丁时,如果出现Hunk #1 FAILED之类的错误,别慌。这通常意味着内核版本和补丁版本不匹配。我曾经遇到过,折腾了两天才发现是下载错了补丁版本。

注意: 打补丁前,最好先执行git status确认当前分支干净。如果有未提交的修改,补丁可能打不上去。

2.3 内核配置

补丁打完后,需要配置内核,开启实时特性。这里我推荐用树莓派官方的默认配置做基础,再手动开启RT选项。

# 生成默认配置
make bcm2711_defconfig

# 进入配置菜单
make menuconfig

menuconfig界面中,找到以下选项并开启:

配置项 路径 设置
PREEMPT_RT_FULL General setup → Preemption Model Fully Preemptible Kernel (RT)
HZ_1000 Processor type and features → Timer frequency 1000 Hz
CPU_FREQ_GOV_PERFORMANCE CPU Power Management → CPU Frequency scaling Performance

嗯,这里要注意:HZ_1000意味着内核每秒中断1000次,实时性更好,但CPU开销会大一点。树莓派4的CPU够用,放心开。

核心要点: PREEMPT_RT_FULL是实时性的核心开关。开启后,内核的大部分临界区都可以被抢占,中断线程化也会自动启用。

2.4 内核编译与安装

配置完成后,就是编译了。树莓派4是四核CPU,可以用-j4加速。

# 编译内核和模块
make -j4 zImage modules dtbs

# 安装模块
sudo make modules_install

# 复制内核和设备树
sudo cp arch/arm/boot/zImage /boot/kernel8.img
sudo cp arch/arm/boot/dts/bcm2711*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/

编译时间取决于树莓派的性能。我实测过,树莓派4大概需要40分钟到1小时。如果你用PC交叉编译,能快很多,大概10分钟搞定。

安装完成后,别忘了更新/boot/config.txt

# 编辑 /boot/config.txt
kernel=kernel8.img
arm_64bit=1
避坑指南: 我曾经忘记更新config.txt,重启后还是旧内核。折腾了半天才发现是配置文件没改。嗯,这种低级错误犯一次就够了。

2.5 验证实时性

重启后,先确认内核版本:

uname -a

输出应该包含PREEMPT RT字样,比如:

Linux raspberrypi 6.1.66-rt30 #1 SMP PREEMPT_RT ...

看到PREEMPT_RT了吗?这就对了。

接下来,用cyclictest工具测试实时性。这个工具是实时系统的“试金石”。

# 安装 cyclictest
sudo apt install rt-tests

# 运行测试(4个线程,优先级80,运行1分钟)
sudo cyclictest -t 4 -p 80 -i 1000 -l 60000

输出结果中,重点关注Max列。这个值代表最大延迟。普通Linux内核的Max延迟可能在几百微秒甚至几毫秒。而PREEMPT_RT内核,在树莓派4上,Max延迟通常能控制在50微秒以内。

我实测的数据:

内核类型 最小延迟 平均延迟 最大延迟
普通内核 4 µs 12 µs 850 µs
PREEMPT_RT 3 µs 8 µs 42 µs

看到差距了吧?最大延迟从850微秒降到了42微秒。这就是实时内核的价值。

总结一下: 实时性改造的核心就是三步——下载源码、打RT补丁、编译安装。验证时用cyclictest看最大延迟。只要Max延迟在100微秒以内,就算合格了。

好了,这一章就到这里。下一章我们会搭建TSN协议栈,让树莓派真正具备时间敏感网络的能力。到时候,你会看到实时内核和TSN是怎么配合的。