linux_learn/learn/AMP-vs-LinuxRT/README.md

210 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Linux+Preempt-RT vs AMP (Linux+RTOS) — 实时系统方案对比
> 目标平台RK35684×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 架构知识CacheMMU内存屏障 | 基本了解即可 | **需要深入理解** |
### 4.2 开发工作量估算
假设最终目标都是实现一个完整的 CAN 协议栈含定时发送突发上送遥控定值文件传输
| 阶段 | Linux+RT | AMP |
|------|:---:|:---:|
| 环境搭建 | 1 ( RT 内核镜像即可) | 1~2 (AMP SDK 环境双编译链JTAG) |
| CAN 驱动 | 0 (SocketCAN 现成) | 1~2 (移植/写裸核 CAN 驱动) |
| 协议栈开发 | 2~4 (POSIX CGDB 调试) | 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μsRT 内核的 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 算力是否够你的保护逻辑