- docs/: 学习资料索引(7份, 涵盖驱动/DTS/AMP/应用层/实时性/STM32/硬件) - learn/CAN/: 电力二次设备CAN协议栈(v2.0, 含帧编解码/XML配置/突发队列) - learn/NPU/: NPU波形故障识别部署指南(5份, 含训练/转换/推理/CAN整合) - learn/AMP-vs-LinuxRT/: 实时方案对比分析 - memory/: Claude Code 记忆文件 - CLAUDE.md: 仓库指导文件 Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| README.md | ||
README.md
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 第 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?
- 创龙的文档也这么建议的(docs/05 第 147-157 行)——先跑通功能,再优化
- AMP 最大的坑不是写代码,是调试——两个核的状态不同步,出了 bug 很难定位
- 电力保护设备里,绝大多数通讯场景不到 1ms 级别——CAN 帧 1Mbps 下一帧才 ~100μs,RT 内核的 20μs 中断延迟完全够
- 你当前的 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 算力是否够你的保护逻辑。