第 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_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 消费。

相关推荐
Adorable老犀牛18 小时前
给运维同行的一个小提议:一起做「不费力的周复盘」,让经验不白费
运维·周报·复盘·反人性·为自己
xlq2232218 小时前
26(下).库的理解与加载
linux·运维·服务器
孤芳剑影18 小时前
Allegro测量查看通孔尺寸方法
嵌入式硬件
爱学习的小囧18 小时前
零门槛!VCF 自动化环境登录 vSphere Supervisor 全教程
运维·服务器·算法·自动化·vmware·虚拟化
银月光科技18 小时前
红外LED加热应用的市场格局与增长潜力
单片机·嵌入式硬件
项目題供诗18 小时前
51单片机入门-蜂鸣器(十一)
单片机·嵌入式硬件·51单片机
wbs_scy18 小时前
Linux 动静态库完全指南:制作、使用、原理与实战
linux·运维·服务器
孙同学_18 小时前
【Linux篇】Socket编程TCP
linux·网络·tcp/ip
沃和莱特18 小时前
Copy as fetch + Skill:自动化问题记录分析的实践与思考
运维·ai·自动化·编程·skills
赛博云推-Twitter热门霸屏工具18 小时前
从手动运营到自动化增长:赛博云推让Twitter推广效率提升10倍
运维·自动化·twitter