第 10 章:OpenAMP 实战——构建 M33 与 Linux 的 RPMsg 消息隧道

在多核系统中,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 工程中,我们需要引入 libmetalopen-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(&params);

// 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_buf128;

// 格式化为 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 消费。

相关推荐
AlfredZhao2 天前
生产环境里,为什么不建议把普通端口直接暴露到公网?
linux·https·443·80
戴为沐3 天前
Linux内存扩容指南
linux
zylyehuo3 天前
Linux 彻底且安全地删除文件
linux
用户805533698034 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297914 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
乘云数字DATABUFF4 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
Web3探索者6 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo6 天前
Linux系统中网线与USB网络共享冲突
linux
荣--6 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森6 天前
动手实战学 Docker — 从零到集群编排完全指南
运维