在 AMP(Asymmetric Multi-Processing,非对称多处理)混合部署架构中,Linux 和 RT-Thread 运行在同一颗芯片的两个不同核心上,如何高效地在两个系统之间传递大数据,是一个核心问题。
上一篇文章介绍了 DSMC 总线方案,适合与 FPGA 等外部设备高速通信。今天我们聚焦另一个场景——睿擎平台 AMP 共享内存(SHM)通信,介绍 RC3562 平台如何利用芯片内置的共享内存机制,实现 Linux 与 RT-Thread 之间的高速数据交换,并提供完整示例代码和实测数据。
在 AMP 混合部署中,Linux 和 RT-Thread 各司其职:
Linux 负责复杂的人机交互、网络通信、文件系统等
RT-Thread 负责实时控制、电机驱动、传感器采集等
两者之间需要频繁交换数据:

传统方案(如 RPMSG)基于消息队列,适合小数据量、事件驱动的通信场景。但当需要传递大数组、实时流数据时,消息队列的多次拷贝会带来显著延迟和 CPU 开销。
共享内存(SHM) 的核心思想是:划定一块物理内存,两个核心都能直接访问,数据无需拷贝,延迟可降至微秒级,是 AMP 双系统大数据量通信的终极方案。
睿擎平台的 RK3562 和 RK3506 芯片在内部 SRAM 区域预留了一块共享内存区域,两个核心都可以直接访问。共享内存区域布局:

关键参数:
● 地址:两块核心映射到同一物理地址 0xc000000,无需额外地址转换
● 大小:2MB(0x200000),适合中等体量的数据交换
● 通知机制:通过 Mailbox 硬件发送中断,告知对方数据已就绪
● 缓存同步:Linux 使用 msync,RT-Thread 使用 AMP_SHM_IOCTL_FLUSH_CACHE / AMP_SHM_IOCTL_INVALID_CACHE
Linux 侧应用程序通过标准 POSIX 接口访问共享内存设备 /dev/amp_shm,核心操作为:open → ioctl → mmap → 读写数据 → msync → munmap。
#include #include #include #include #include #include #include #include #include #define AMP_SHM_IOCTL_BASE 'A'#define AMP_SHM_IOCTL_KICK _IO(AMP_SHM_IOCTL_BASE, 1)#define AMP_SHM_IOCTL_GET_SIZE _IOR(AMP_SHM_IOCTL_BASE, 2, size_t) int main(int argc, char **argv){ const char *dev_name = argv[1]; int fd = open(dev_name, O_RDWR); if (fd < 0) { perror("open"); return -1; } /* ========== 发送通知(Linux → RT-Thread)========== */ if (!strcmp(argv[2], "send_notify")) { ioctl(fd, AMP_SHM_IOCTL_KICK); printf("send a notify.\n"); } /* ========== 等待通知(Linux 阻塞等待 RT-Thread 发来的中断)========== */ if (!strcmp(argv[2], "wait_notify")) { struct pollfd pfd = { .fd = fd, .events = POLLIN }; poll(&pfd, 1, -1); printf("receive a notify.\n"); } /* ========== 写入数据(Linux → RT-Thread)========== */ if (!strcmp(argv[2], "write") && argc == 5) { uint32_t size; ioctl(fd, AMP_SHM_IOCTL_GET_SIZE, &size); uint8_t *vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); uint32_t offset = (uint32_t)strtoul(argv[3], NULL, 0); const char *str = argv[4]; memcpy(vaddr + offset, str, strlen(str)); msync(vaddr + offset, strlen(str), MS_SYNC); munmap(vaddr, size); } /* ========== 读取数据(Linux ← RT-Thread)========== */ if (!strcmp(argv[2], "read") && argc == 5) { uint32_t size; ioctl(fd, AMP_SHM_IOCTL_GET_SIZE, &size); uint8_t *vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); uint32_t offset = (uint32_t)strtoul(argv[3], NULL, 0); uint32_t len = (uint32_t)strtoul(argv[4], NULL, 0); msync(vaddr + offset, len, MS_INVALIDATE); for (uint32_t i = 0; i < len; i++) { printf("[%02u] = %02x\n", i, *(vaddr + offset + i)); } munmap(vaddr, size); } close(fd); return 0;}
编译方式(使用 SDK 构建系统):
# 使用 SDK 提供的 cmake 配置交叉编译cd /path/to/shm_demomkdir build && cd buildcmake .. -DTOOLCHAIN_ROOT=/path/to/toolchainmake# 产出:amp_shm_device_app(部署到开发板 Linux 文件系统)
RT-Thread 侧通过设备框架(RT-Device)访问共享内存,设备名为 amp-shm。MSH 命令 amp_shm_test 提供与 Linux 侧对应的所有操作。
#include #include #define AMP_SHM_IOCTL_GET_INFO 0x40#define AMP_SHM_IOCTL_KICK 0x41#define AMP_SHM_IOCTL_WAIT 0x42#define AMP_SHM_IOCTL_MAP 0x43#define AMP_SHM_IOCTL_UNMAP 0x44#define AMP_SHM_IOCTL_FLUSH_CACHE 0x45#define AMP_SHM_IOCTL_INVALID_CACHE 0x46 struct amp_shm_args { void *vaddr; rt_uint32_t size; rt_uint32_t cache_offset; rt_uint32_t cache_len;}; static int amp_shm_test(int argc, char **argv){ rt_device_t dev = rt_device_find(argv[1]); struct amp_shm_args args = { 0 }; rt_device_open(dev, 0); /* ========== 发送通知(RT-Thread → Linux)========== */ if (!strcmp(argv[2], "send_notify")) { rt_device_control(dev, AMP_SHM_IOCTL_KICK, RT_NULL); } /* ========== 等待通知(RT-Thread 阻塞等待 Linux 发来的中断)========== */ if (!strcmp(argv[2], "wait_notify")) { rt_device_control(dev, AMP_SHM_IOCTL_WAIT, RT_NULL); } /* ========== 写入数据(RT-Thread → Linux)========== */ if (!strcmp(argv[2], "write") && argc == 5) { rt_device_control(dev, AMP_SHM_IOCTL_GET_INFO, &args); rt_device_control(dev, AMP_SHM_IOCTL_MAP, &args); rt_uint8_t *vaddr = (rt_uint8_t *)args.vaddr; rt_memcpy(vaddr + atol(argv[3]), argv[4], rt_strlen(argv[4])); /* 刷新缓存,确保数据写回物理内存 */ args.cache_offset = atol(argv[3]); args.cache_len = rt_strlen(argv[4]); rt_device_control(dev, AMP_SHM_IOCTL_FLUSH_CACHE, &args); rt_device_control(dev, AMP_SHM_IOCTL_UNMAP, &args); } /* ========== 读取数据(RT-Thread ← Linux)========== */ if (!strcmp(argv[2], "read") && argc == 5) { rt_device_control(dev, AMP_SHM_IOCTL_GET_INFO, &args); rt_device_control(dev, AMP_SHM_IOCTL_MAP, &args); rt_uint8_t *vaddr = (rt_uint8_t *)args.vaddr; rt_uint32_t offset = atol(argv[3]); rt_uint32_t len = atol(argv[4]); /* 使 CPU 缓存失效,从物理内存读取最新数据 */ args.cache_offset = offset; args.cache_len = len; rt_device_control(dev, AMP_SHM_IOCTL_INVALID_CACHE, &args); for (int i = 0; i < len; i++) { rt_kprintf("[%2d] = %02x\n", i, *(vaddr + offset + i)); } rt_device_control(dev, AMP_SHM_IOCTL_UNMAP, &args); } return 0;} MSH_CMD_EXPORT(amp_shm_test, amp shm test);

Linux 发通知,RT-Thread 等待:
# RT-Thread 串口终端 - 阻塞等待 Linux 发来的中断msh />amp_shm_test amp-shm wait_notify # Linux 串口终端 - 发送通知到 RT-Threadroot@rc3562:/# amp_shm_device_app /dev/amp_shm send_notifysend a notify.
RT-Thread 发通知,Linux 等待:
# Linux 串口终端 - 阻塞等待 RT-Thread 发来的中断root@rc3562:/# amp_shm_device_app /dev/amp_shm wait_notify # RT-Thread 串口终端 - 发送通知到 Linuxmsh />amp_shm_test amp-shm send_notify
Linux 写数据,RT-Thread 读取:
# Linux 侧 - 向共享内存偏移 0 处写入 "hello"root@rc3562:/# amp_shm_device_app /dev/amp_shm write 0 "hello" # RT-Thread 侧 - 从共享内存偏移 0 处读取 16 字节msh />amp_shm_test amp-shm read 0 16[ 0] = 68 (h)[ 1] = 65 (e)[ 2] = 6c (l)[ 3] = 6c (l)[ 4] = 6f (o)...(后续字节为 0x00)
RT-Thread 写数据,Linux 读取:
# RT-Thread 侧 - 向共享内存偏移 0 处写入 "world"msh />amp_shm_test amp-shm write 0 "world" # Linux 侧 - 从共享内存偏移 0 处读取 16 字节root@rc3562:/# amp_shm_device_app /dev/amp_shm read 0 16[00] = 77 (w)[01] = 6f (o)[02] = 72 (r)[03] = 6c (l)[04] = 64 (d)[05] = 00 (.)…

Linux 侧做运动学规划和视觉处理,通过共享内存将目标轨迹高速下发到 RT-Thread;RT-Thread 侧控制电机,通过共享内存回传编码器位置数据。
7.2 高速传感器采集

RT-Thread 侧以 100kHz 采样率采集多路传感器数据,通过共享内存以 10+ MB/s 的速度传输到 Linux 侧做存储和分析。
本文基于实际 SDK 源码,完整介绍了睿擎平台 AMP 共享内存通信机制:
理解共享内存在 AMP 架构中的定位和优势(2MB SRAM,Mailbox 中断通知)
掌握 Linux 侧 POSIX 接口(open/mmap/msync)使用方法
掌握 RT-Thread 侧设备框架接口(rt_device_* + IOCTL)使用方法
理解缓存同步机制(FLUSH_CACHE / INVALID_CACHE)
共享内存是睿擎平台 AMP 双系统通信的性能天花板,适合对实时性和带宽有极致要求的工业场景。结合 DSMC(外部设备高速通信)和 RPMSG(控制命令传输),睿擎平台提供了完整的 AMP 通信解决方案,开发者可以根据场景灵活选择。
相关文档:
● 睿擎平台开发文档
● RuiChing Studio 下载
示例工程:
● Linux 侧:shm_demo/amp_shm_device_app.c
● RT-Thread 侧:
08_misc_amp_factory_default/applications/amp_shm_device_app.c
全部0条评论
快来发表一下你的评论吧 !