一、简介:为什么国产多核必须“自己调”?
背景:飞腾芯片(ARMv8 架构)已批量应用于能源、矿山、轨道交通等关键基础设施,核心数从 4 核到 64 核不等。
痛点:默认调度器侧重吞吐,实时任务(<1 ms 控制环)常被负载均衡算法“搬来搬去”,导致:
中断延迟抖动 > 200 µs
双核同时访问外设寄存器 → 总线争用
非实时任务污染 L2 Cache,实时任务命中率下降
价值:掌握“核心绑定+隔离+负载均衡”三件套,同等硬件下实时抖动下降 70%,为后续 SIL/PL 认证打下量化基础。
二、核心概念:5 个关键词先搞懂
| 名词 | 一句话 | 飞腾平台差异 |
|---|---|---|
| CPU Affinity | 把任务钉在指定核心运行 | 飞腾 L3 共享,绑定时需考虑 Cluster |
| isolcpus | 内核启动参数,隔离核心不参与调度 | 飞腾 GICv3 支持,irqbalance 需手动关 |
| taskset | 用户态绑定工具 | 与 x86 用法完全一致 |
| sched_setaffinity | 代码级绑定 | 同 ARM Generic |
| PREEMPT_RT | 实时补丁,使内核可完全抢占 | 飞腾官方已发布 rt 分支 |
三、环境准备:10 分钟搭好“飞腾多核实验室”
1. 硬件
FT-2000/4 工业板卡(4 核 Cortex-A53 @1.5 GHz)
串口线 ×1(115200 8N1)
2. 软件
| 组件 | 版本 | 获取方式 |
|---|---|---|
| 实时内核 | linux-5.15-ft-rt30 | 飞腾 Git 开源 |
| 根文件系统 | Ubuntu 20.04 arm64 | 官方 prebuild |
| 交叉工具链 | gcc-linaro-11.3 | sudo apt install gcc-aarch64-linux-gnu |
3. 一键编译内核(可复制)
#!/bin/bash # build_ft_rt.sh git clone https://gitee.com/phytium/linux.git -b v5.15-ft-rt cd linux export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- make phytium_defconfig ./scripts/config -e CONFIG_PREEMPT_RT make -j$(nproc) Image dtbs # 输出:arch/arm64/boot/Image4. 部署
通过
tftpboot或烧写到 eMMC,串口进入系统。
四、应用场景(300 字)
某矿山 5G+远程掘进系统采用 FT-2000/4 做车载控制器:
Core0 运行 EtherCAT 主站,周期 250 µs;
Core1 跑 5G TSN 协议栈,中断密集;
Core2/3 负责数据上云与本地 HMI。
现场出现 EtherCAT 偶发延迟 > 800 µs → 导致液压臂抖动。经分析,Linux 负载均衡将 Core0 的实时任务短暂迁移到 Core1,与 5G 中断冲突。使用本文“isolcpus + irqbalance 关闭 + taskset”方案后,Core0 专核专用,中断延迟稳定在 65 µs 以内,抖动下降 70%,通过矿山安全监察局验收。
五、实际案例与步骤:从“默认调度”到“专核专用”
实验目标:把周期 500 µs 实时任务固定在 Core2,禁止调度器迁移。
5.1 隔离核心(boot 阶段完成)
编辑/boot/grub/grub.cfg追加:
linux /boot/Image isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3解释:
isolcpus=2,3→ 内核不再将普通任务放到 2/3 核nohz_full→ 动态 tick 关闭,减少时钟中断rcu_nocbs→ RCU 回调卸载,避免实时核被 RCU 打扰
保存后sudo reboot,串口确认:
cat /proc/cmdline | grep isolcpus5.2 关闭 irqbalance(防止中断漂移)
sudo systemctl stop irqbalance sudo systemctl disable irqbalance5.3 将外设中断绑到非实时核
查看 EtherCAT 网卡中断号:
grep eth0 /proc/interrupts # 示例: 40: 0 GICv3 40 eth0绑到 Core0:
echo 1 > /proc/irq/40/smp_affinity # 位0 = Core05.4 用户态启动实时任务并绑核
/* cyclic_task.c */ #define _GNU_SOURCE #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <sys/mman.h> void *rt_loop(void *arg) { /* 绑到 Core2 */ cpu_set_t set; CPU_ZERO(&set); CPU_SET(2, &set); pthread_setaffinity_np(pthread_self(), sizeof(set), &set); /* 内存锁页 */ mlockall(MCL_CURRENT | MCL_FUTURE); /* 500 µs 循环 */ for (int i = 0; i < 10000; i++) { usleep(500); /* 实际用 timerfd 更精准 */ } return NULL; } int main() { pthread_t tid; pthread_attr_t attr; struct sched_param param = { .sched_priority = 90 }; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); pthread_attr_setschedparam(&attr, ¶m); pthread_create(&tid, &attr, rt_loop, NULL); pthread_join(tid, NULL); return 0; }交叉编译:
aarch64-linux-gnu-gcc cyclic_task.c -o cyclic_task -pthread板端运行:
sudo ./cyclic_task5.5 验证效果
调度迁移检查
ps -eo pid,psr,comm | grep cyclic_task # 应始终显示 Core2延迟 histogram
sudo cyclictest -p90 -Sp90 -i200 -d60s -m \ -a2 -A2 # 只在 Core2 运行典型结果:
Min: 8 µs Avg: 14 µs Max: 38 µs ← 未隔离前 Max=210 µs
六、常见问题与解答(FAQ)
| 问题 | 现象 | 解决 |
|---|---|---|
| isolcpus 后 SSH 无法登录 | 所有任务挤到 Core0,负载 100% | 保留 Core0 给系统,隔离 2,3 即可 |
| 中断 affinity 写入失败 | 提示“Invalid argument” | 确认 irq 号存在;某些 GIC 虚拟中断不可绑 |
| cyclictest Max 仍 > 100 µs | BIOS 电源管理未关 | 进 BIOS 关闭 Dynamic Turbo、CPU C6 |
| 任务偶尔飘到 Core0 | 代码未 mlockall,缺页异常 | 加 mlockall(MCL_CURRENT | MCL_FUTURE) |
| 热插拔 USB 导致延迟尖峰 | USB 中断共享在 Core2 | 把 USB 中断绑回 Core0:echo 1 > /proc/irq/XX/smp_affinity |
七、实践建议与最佳实践
“系统核 + 实时核”分区
Core0/1 跑 OS + 网络中断,Core2/3 专跑实时任务,永不重叠。IRQ 亲和度脚本化
把/proc/irq/*/smp_affinity设置写成 systemd 服务,开机自启,防止板卡更换后遗忘。用 cgroups v2 限带宽
对非实时组限制cpu.max=50%,确保实时核满载时系统核仍可响应。双核锁步安全场景
若需 SIL 2,可把 Core2/3 跑相同任务,硬件比较器逐周期校验,诊断覆盖率 > 99%。版本锁定
内核、设备树、U-Boot 哈希值写入《安全配置清单》,任何升级走变更流程。热升级
使用 kexec 快速加载新 RT 内核,<30 s 完成重启,矿山 24 h 连续生产不中断。
八、总结:一张脑图带走全部要点
飞腾多核实时调度优化 ├─ 隔离:isolcpus + nohz_full + rcu_nocbs ├─ 绑中断:/proc/irq/*/smp_affinity ├─ 绑任务:taskset / pthread_setaffinity_np ├─ 测延迟:cyclictest -aCoreID └─ 文档:affinity 脚本 + 版本清单国产芯 + 实时系统 = 自主可控的工业底座。
掌握本文“隔离-绑定-测量”三步法,你就能:
让 EtherCAT 周期抖动 < 50 µs,机械臂平稳无颤抖
让 5G TSN 与实时控制同芯片共存,互不干扰
让 auditor 看到 99.9% 任务稳在指定核,审计一次通过
立刻登录你的飞腾板卡,复制/proc/cmdline加上isolcpus=2,3,重启后跑一遍cyclictest——实时性提升肉眼可见,国产多核真正“服服帖帖”!