# Linux+Preempt-RT vs AMP (Linux+RTOS) — 实时系统方案对比 > 目标平台:RK3568(4×Cortex-A55 + 1×Cortex-M0) > 应用场景:电力二次保护设备 CAN 通讯 --- ## 一、两种方案一句话概括 | 方案 | 核心思路 | |------|------| | **Linux + Preempt-RT** | 给 Linux 内核打实时补丁,让原本"不可抢占"的内核路径变得可抢占,把最坏延迟从 200μs+ 压到 20μs 以内。所有代码(协议栈、业务逻辑、驱动)都在同一个 Linux 里跑。 | | **AMP (Linux + RTOS)** | 硬件分家:1~3 个 A55 核跑 Linux 做复杂业务(网络、文件系统、协议栈上层),另外的核(A55 或 M0)跑 RT-Thread/Baremetal 做硬实时任务(CAN 收发、保护逻辑、ADC 采集)。中间靠共享内存 + 中断(rpmsg)通信。 | --- ## 二、实时性能对比 ### 2.1 中断响应延迟 这是最核心的指标——从 CAN 控制器收到一帧到 CPU 开始处理的时间: | 指标 | Linux+RT | AMP (RT-Thread 裸核) | |------|:---:|:---:| | **典型中断延迟** | 5~15 μs | < 1 μs | | **最坏中断延迟** | 15~30 μs | < 3 μs | | **延迟抖动 (jitter)** | ±10 μs | ±1 μs | | **确定性** | 概率性(99.9% 在预算内) | 确定性(100% 在预算内) | > 来源:创龙文档,RT 内核 cyclictest 测试 max < 20μs;裸核无操作系统调度开销,中断延迟仅取决于 CPU 频率和中断控制器。 ### 2.2 你的 CAN 场景对号入座 | 场景 | 延迟要求 | Linux+RT 够不够 | AMP 必要性 | |------|:---:|:---:|:---:| | CAN 帧收发(标准 1Mbps) | < 100μs | ✅ 轻松满足 | 不必要 | | CAN FD 高速收发(5Mbps) | < 50μs | ✅ 基本满足 | 有富余 | | 保护动作出口(从判断到出口继电器) | < 1ms | ✅ 满足 | 不必要 | | 多通道同步 ADC + CAN 突发 | < 10μs jitter | ⚠️ 临界 | **AMP 更安全** | | 微秒级 SOE 打时戳 | < 5μs jitter | ❌ 不够 | **必须 AMP** | | 100μs 周期实时控制(如 SVG/APF) | < 50μs jitter | ❌ 不够 | **必须 AMP** | --- ## 三、功能效果对比 ### 3.1 Linux+Preempt-RT ``` ┌──────────────────────────────────────────────┐ │ 单块 Linux 内核 (PREEMPT_RT) │ │ │ │ ┌──────────┐ ┌───────────┐ ┌─────────────┐ │ │ │ CAN协议栈 │ │ 保护逻辑 │ │ 文件系统/NET │ │ │ │ SCHED_FIFO│ │ SCHED_FIFO │ │ 普通线程 │ │ │ │ prio=80 │ │ prio=70 │ │ │ │ │ └──────────┘ └───────────┘ └─────────────┘ │ │ ┌──────────────────────────────────────────┐│ │ │ 全部共享同一个内核、同一套驱动 ││ │ └──────────────────────────────────────────┘│ └──────────────────────────────────────────────┘ 优点: ✅ 所有代码一个工程,开发/调试/GDB 全统一 ✅ SocketCAN 接口直接用,驱动现成 ✅ POSIX 线程、文件系统、网络全有 ✅ 丢帧、超时等异常处理逻辑好写 缺点: ✗ 最坏延迟 20μs(够99%场景,但不是"硬实时") ✗ 内核态某些路径仍不可抢占(如某些 spinlock 临界区) ✗ 系统负载高时抖动会增大 ``` ### 3.2 AMP (Linux + RT-Thread) ``` ┌──────────────────┐ rpmsg(共享内存+中断) ┌──────────────────┐ │ Core0: Linux │ ◄══════════════════► │ Core2: RT-Thread │ │ (CA55) │ │ (CA55, 裸核) │ │ │ │ │ │ • CAN 协议栈上层 │ ←── CAN 帧、控制命令 │ • CAN FD 直接收发 │ │ • 定值管理 │ │ • SOE 打时戳 │ │ • 录波文件存储 │ ──── 录波数据 ──────► │ • 保护逻辑判断 │ │ • MQTT 上送 │ │ • GPIO 出口继电器 │ │ • GUI/调试 │ │ • 100μs 周期控制 │ │ │ │ │ │ 应用层, 复杂业务 │ │ 实时层, 确定性任务 │ └──────────────────┘ └──────────────────┘ 优点: ✅ 真正的硬实时(裸核中断延迟 < 1μs) ✅ 实时任务不受 Linux 调度器影响 ✅ 实时核崩溃不影响 Linux 核(故障隔离) ✅ Linux 核可以做复杂的事(录波分析、文件压缩、网络通讯) 缺点: ✗ 两套代码、两个编译链、两种调试方式 ✗ rpmsg 通信有开销(~10-50μs 的单次传输延迟) ✗ 核间通信协议需自己设计(Linux侧和RT-Thread侧的数据结构要对齐) ✗ 没有 SocketCAN 这样的现成接口,裸核 CAN 驱动需要自己写/移植 ``` --- ## 四、开发难度对比 ### 4.1 技能要求 | 技能点 | Linux+RT | AMP | |--------|:---:|:---:| | Linux 应用编程 (POSIX, SocketCAN) | ✅ 需要 | ✅ 需要 | | Linux 内核/驱动 | 基本了解即可 | 不需要(Linux 侧) | | RTOS 编程 (RT-Thread) | 不需要 | **必须掌握** | | 裸核编程 (中断、寄存器、Linker Script) | 不需要 | **必须掌握** | | 交叉编译链 | 1 套 (aarch64-linux-gnu-) | **2 套** (Linux + bare-metal) | | JTAG 调试 | 不需要 | **需要**(调试裸核) | | 共享内存/核间通信协议设计 | 不需要 | **需要** | | ARM 架构知识(Cache、MMU、内存屏障) | 基本了解即可 | **需要深入理解** | ### 4.2 开发工作量估算 假设最终目标都是实现一个完整的 CAN 协议栈(含定时发送、突发上送、遥控、定值、文件传输): | 阶段 | Linux+RT | AMP | |------|:---:|:---:| | 环境搭建 | 1 天 (换 RT 内核镜像即可) | 1~2 周 (AMP SDK 环境、双编译链、JTAG) | | CAN 驱动 | 0 天 (SocketCAN 现成) | 1~2 周 (移植/写裸核 CAN 驱动) | | 协议栈开发 | 2~4 周 (POSIX C,GDB 调试) | 4~8 周 (双端开发 + rpmsg 协议) | | 实时优化 | 1 周 (SCHED_FIFO + 绑核 + 锁内存) | 1~2 周 (裸核本来就有确定性) | | 调试/稳定性 | 1 周 (GDB/valgrind/perf 工具链成熟) | 2~4 周 (核间问题难复现、难定位) | | **总计** | **约 5~8 周** | **约 9~18 周** | ### 4.3 调试难度 ``` Linux+RT: GDB → 打断点 → 看变量 → 搞定 所有线程在一个进程空间,crash 日志清晰 AMP: Linux 核: GDB 可调 裸核: JTAG (硬件调试器) + printf 通过串口 跨核问题: 裸核死掉,Linux 侧完全不知道发生了什么 只能靠看共享内存 dump + 猜 ``` --- ## 五、针对你的场景的建议 ### 首先确认:你需要的"实时"到底是哪个级别? > 对照 [docs/05-实时性与系统优化.md](docs/05-实时性与系统优化.md) 第 7-17 行的需求表: | 你的需求场景 | 实时级别 | 推荐方案 | |------|:---:|------| | CAN 帧收发(1Mbps, 最大 8 字节) | 软实时 | **Linux+RT** ✅ | | CAN FD 收发(5Mbps, 64 字节) | 软实时 | **Linux+RT** ✅ | | 遥控选择-返校-执行(ms 级) | 软实时 | **Linux+RT** ✅ | | 定时遥测上送(100ms~1s) | 非实时 | **Linux+RT** ✅ | | 保护动作出口(从采样到跳闸 < 30ms) | 硬实时 | **Linux+RT** ⚠️ 基本够 | | 微秒级 SOE 打时戳 | 硬实时 | **AMP** ✅ | | 100μs 周期快速控制环 | 硬实时 | **AMP** ✅ | ### 结论:分阶段路线 ``` 阶段 1 (当前): Linux+RT — 跑通 CAN 协议栈 ├── 标准 Linux 内核上把协议栈功能全部开发完 ├── 用 SocketCAN 收发,GDB 调试 ├── 功能稳定后 → 切 RT 内核 ├── 加 SCHED_FIFO + 绑核 + mlockall └── cyclictest 验证 → 基本满足 90% 的电力保护需求 阶段 2 (未来,如果有需要): AMP 硬实时 前提条件: ├── 业务确实需要 <5μs 确定性(如 SOE 打时戳、100μs 控制环) ├── 准备好了 JTAG 调试器 ├── 团队有人熟悉 RT-Thread 或裸核编程 └── 架构拆分: Linux 做协议栈 + 界面,裸核做收发 + 保护逻辑 ``` ### 为什么不一开始就上 AMP? 1. **创龙的文档也这么建议的**([docs/05](docs/05-实时性与系统优化.md) 第 147-157 行)——先跑通功能,再优化 2. **AMP 最大的坑不是写代码,是调试**——两个核的状态不同步,出了 bug 很难定位 3. 电力保护设备里,**绝大多数通讯场景不到 1ms 级别**——CAN 帧 1Mbps 下一帧才 ~100μs,RT 内核的 20μs 中断延迟完全够 4. 你当前的 CAN 协议栈设计(遥控超时 30 秒、遥测周期 500ms)也是 ms~s 级别,不是 μs 级别 --- ## 六、补充:还有一个中间方案 — Linux + M0 协处理 RK3568 内部有一颗 **Cortex-M0**(不是 A55),可以跑极简裸核代码: ``` A55 (Linux+RT): M0 核: CAN 协议栈 ←── mailbox/IPCC ──→ CAN FD 收发 保护逻辑 GPIO 快速出口 文件系统 SOE 打时戳 ``` - M0 频率低(~200MHz),但中断响应极快 - Rockchip AMP SDK 主要就是面向 M0 核的 - 不需要占用 A55 核,Linux 侧 4 核全保留 - 适合把"极少量的硬实时逻辑"剥离出去 这个方案比 AMP(A55+RT-Thread) 更轻量,但需要评估 M0 算力是否够你的保护逻辑。