在多核系统中,M33 采集到的 IMU 数据如果只能从自己的串口打印,那 A35 侧的 GUI 和云端应用就成了摆设。我们要建立一套标准化的通讯协议------OpenAMP (Open Asymmetric Multi-Processing) 。它基于 virtio 队列和 RPMsg 总线,是异构多核交互的工业标准。
10.1 RPMsg 工作原理
RPMsg (Remote Processor Messaging) 就像是核间局域网。
-
端点 (Endpoint):每个通讯频道都有一个地址(类似于端口号)。
-
共享内存 :数据存放在第 7 章划定的
Shared Memory中。 -
中断通知 :M33 写完数据后,触发一个 IPCC (Inter-Processor Communication Controller) 中断通知 A35。
10.2 M33 侧:移植 OpenAMP 库
在 M33 工程中,我们需要引入 libmetal 和 open-amp 框架。STM32CubeMP2 SDK 已经提供了移植好的代码。
1. 初始化 OpenAMP 资源
/* 定义一个 RPMsg 终端 */
static struct rpmsg_endpoint my_endpoint;
void OpenAMP_Init(void) {
// 1. 初始化硬件邮箱 (IPCC)
MX_IPCC_Init();
// 2. 初始化 libmetal 环境
metal_init(¶ms);
// 3. 初始化 RPMsg 实例
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
// 4. 创建本地端点,等待 Linux 连接
rpmsg_create_ept(&my_endpoint, &rpmsg_vdev, "rpmsg-raw",
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
my_endpoint_cb, // 收到消息的回调函数
rpmsg_service_unbind);
}
10.3 深度实战:将 IMU 数据打包发送
我们要把第 5 章采集到的 IMU_Data_t 结构体,通过 OpenAMP 发往 A35。
void Send_IMU_To_Linux(IMU_Data_t *data) {
char msg_buf[128];
// 格式化为 JSON 或二进制,这里用简单的字符串便于调试
int len = snprintf(msg_buf, sizeof(msg_buf),
"IMU:%d,%d,%d", data->ax, data->ay, data->az);
// 发送数据到 Linux 侧
if (rpmsg_send(&my_endpoint, msg_buf, len) != RL_SUCCESS) {
// 如果发送失败(缓冲区满),可以记录丢包数
}
}
10.4 Linux 侧:开启 RPMsg 驱动支持
在 Linux 内核配置(make menuconfig)中,需确保以下模块开启:
-
CONFIG_RPMSG_CHAR(允许在用户态通过 /dev/rpmsgX 访问) -
CONFIG_REMOTEPROC(远程处理器管理) -
CONFIG_STM32_IPCC(硬件信箱驱动)
10.5 验证:Linux 端的"收件箱"
当 M33 运行并开启 OpenAMP 后,Linux 启动时会在控制台看到: virtio_rpmsg_bus virtio0: creating channel rpmsg-raw addr 0x400
你可以直接在终端测试:
查看生成的设备节点
ls /dev/rpmsg_ctrl*
绑定端点并读取数据
stty -F /dev/rpmsg0 raw
cat /dev/rpmsg0
如果你在屏幕上看到了 M33 发出的 IMU:xxx,xxx,xxx,恭喜你,跨核通讯的高速公路已经通车!
10.6 性能瓶颈:为什么不用读写锁?
这是回答你在开篇提到的痛点:
-
传统读写锁:会导致 M33 等待 A35 释放总线,如果 A35 正在处理高负载 GUI 任务,M33 的采集就会被阻塞。
-
OpenAMP 方案 :它是异步非阻塞的。M33 只负责把数据丢进共享内存的环形队列(Ring Buffer),然后发个"敲门"信号(中断)就走。即便 A35 还没来得及看,M33 也可以继续采集下一帧。
10.7 避坑指南 (Debug Tips)
-
陷阱:资源释放顺序。如果重启 A35 Linux,M33 侧必须检测到 RPMsg 链路断开并重置虚拟队列,否则 A35 无法再次连接。
-
陷阱:内存属性不匹配。确保 Linux 和 M33 看到这块共享内存的 Cache 策略完全一致(建议全部设为 Non-cacheable)。
-
陷阱:地址对齐。OpenAMP 的缓冲区对齐要求非常严格(通常 512 字节对齐),如果链接脚本没写好,会导致初始化失败。
章节小结
本章我们实现了多核协同的最核心能力:数据流转。M33 采集,Linux 消费。