关键词:全志D1、Linux、RT‑Thread、AMP、双系统、RPMsg、异构核
一、为什么要在 D1 上跑双系统?
全志 D1 是 RISC‑V 应用处理器,
跑 Linux 没问题,但:
Linux 实时性差
电机 / PWM / 采集需要硬实时
不想全扔给裸机
👉 最优雅解法:Linux(主控)+ RT‑Thread(实时核)= AMP 架构
二、双系统架构(AMP)
CPU0 → Linux (OpenWrt /
Buildroot)
CPU1 → RT‑Thread (baremetal
/ SMP=off)
共享:
- 共享内存
- RPMsg / VirtIO
- 中断(软中断 / IPI)
✅ 两个系统各自独立
✅ 通过 共享内存 + 邮箱机制通信
三、核心思路四步走
Linux 启动后,不唤醒 CPU1
用 remoteproc 加载 RT‑Thread 固件
RT‑Thread 在 CPU1 上运行
两系统通过 RPMsg 通信
四、Linux 侧:预留 CPU 与内存
1️⃣ 设备树中保留 CPU1
/ {
cpus {
cpu@1 {
status = "disabled";
};
};
};
2️⃣ 预留共享内存
reserved-memory {
rt_shm: shm@48000000 {
reg = <0x48000000 0x0010
0000>;
no-map;
};
};
3️⃣ remoteproc 节点
remoteproc0: remoteproc@0 {
compatible = "sunxi,d1-rproc";
memory-region = <&rt_shm>;
status = "okay";
};
五、RT‑Thread 侧(CPU1 固件)
1️⃣ 入口禁止 SMP
#define RT_CPUS 1
rt_hw_cpu_disable(0);
2️⃣ 映射共享内存
#define SHM_BASE 0x48000000
volatile struct rpmsg_shm
*shm =
(void *)SHM_BASE;
3️⃣ RPMsg 初始化
rpmsg_lite_remote_init(
SHM_BASE,
RPMSG_VQ_ID,
VRING_ALIGN
);
六、双系统通信示例
Linux → RT‑Thread
echo "led_on" > /dev/rpmsg
_ctrl
RT‑Thread 接收
rpmsg_lite_recv(ept, buf,
&len);
if (!strcmp(buf, "led_on"))
rt_pin_write(LED_PIN,
PIN_HIGH);
✅ 控制实时外设
✅ Linux 只管业务逻辑
七、启动流程总结
U‑Boot
↓
Linux 启动(CPU0)
↓
remoteproc 加载 .elf
↓
CPU1 启动 RT‑Thread
↓
RPMsg 通道建立
八、常见坑位
❌ CPU1 被 Linux SMP 接管 → 必冲突
❌ 共享内存未 no‑map → Linux 可能踩内存
❌ RPMsg vring 地址不一致 → 通信失败
❌ 中断号(IPI)配置错误 → 收不到消息
✅ 先单独验证 RT‑Thread 在 CPU1 能否运行
✅ 再用最小 RPMsg ping‑pong 测试
九、适用场景
十、写在最后
Linux + RTOS 不是“炫技”,而是架构上的合理分工。
D1 上跑 Linux + RT‑Thread:
Linux 负责“聪明”
RT‑Thread 负责“准时”
如果你也在玩 D1 或异构多核,
欢迎评论区交流踩坑经验 👇
原创声明:
本文由作者亲自编写而成,未经允许,不得私自转载,谢谢你阅读我写的文章,希望能在学习和工作中给你带来些许帮助,欢迎在评论区发表独到的见解,我们互相交流,相互进步。