210 lines
9.9 KiB
Markdown
210 lines
9.9 KiB
Markdown
# 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 算力是否够你的保护逻辑。
|