一、Mailbox与RPMsg概述:异构多核通信的起点

各位同学,咱们今天聊的这东西,说白了就是让多个处理器核心能好好说话。你想想看,现在的嵌入式系统,动不动就是双核、四核,甚至更多。而且这些核心还不一定是同一种架构——ARM跑Linux,DSP做音频处理,RISC-V管安全,这怎么协同?

我最早接触这个领域是在做一款车机芯片的时候。主控是Cortex-A72,协处理器是Cortex-M4,两边要共享传感器数据。当时我天真地以为,直接读写共享内存就行了。结果呢?数据竞争、缓存一致性问题,折腾了整整两周。嗯,从那以后我就明白了——异构多核通信,必须有一套规范的机制。

1.1 异构多核通信背景

先说说为什么需要异构多核。不是所有任务都适合跑在同一个处理器上:

  • 实时性要求:控制类任务需要微秒级响应,Linux的调度延迟扛不住
  • 功耗约束:DSP或MCU处理音频/传感器,比大核省电一个数量级
  • 安全隔离:功能安全等级ASIL-D的代码,不能和普通应用混在一起
  • 专用加速:NPU做AI推理,GPU做渲染,各有各的架构

所以现在的SoC设计,普遍采用主从架构或对称多处理的混合模式。主核跑Linux/Android,从核跑RTOS或裸机。它们之间怎么通信?这就是Mailbox和RPMsg要解决的问题。

核心矛盾:不同核心有各自的内存空间、中断系统和时钟域。直接共享内存就像两个人在不同房间,隔着墙喊话——听不清,还容易撞车。

1.2 Mailbox硬件原理

Mailbox,直译就是“邮箱”。它的硬件结构其实很简单,我画个图你就明白了。

Mailbox 硬件结构示意图 CPU0 (主核) Cortex-A72 Linux CPU1 (从核) Cortex-M4 FreeRTOS Mailbox 控制器 发送寄存器 (Tx) 接收寄存器 (Rx) 状态寄存器 (SR) 中断控制 (ICR) 共享内存 (Shared Memory) 数据缓冲区 / RPMsg 消息体 Mailbox 负责传递“通知”和“控制信息”,真正的数据通过共享内存传输 —— 就像你收到一封快递通知,但包裹在驿站自取

Mailbox的核心机制,我总结为三点:

  1. 寄存器对:每个方向有一组发送/接收寄存器,写数据触发硬件中断
  2. 中断通知:发送方写完寄存器,硬件自动向接收方产生中断
  3. 状态同步:通过状态寄存器判断数据是否被取走,避免覆盖

避坑指南:我曾经在一个项目中,把Mailbox寄存器地址配错了。结果A核发消息,B核收不到,排查了三天。后来发现是地址偏移量少算了0x10。所以,一定要对照芯片手册,逐位确认寄存器偏移。

1.3 RPMsg协议栈简介

Mailbox解决了“怎么通知”的问题,但没解决“通知什么”和“怎么解析”。RPMsg就是干这个的。

RPMsg的全称是Remote Processor Messaging,是Linux内核提供的一套框架。它定义了一套标准化的消息格式和传输流程。说白了,就是给Mailbox穿上一件“协议外衣”。

层级 组件 职责
应用层 用户态驱动 / 应用 发送和接收业务消息
传输层 RPMsg 核心 消息分帧、通道管理、端点寻址
数据链路层 VirtIO / 共享内存 环形缓冲区、数据搬运
物理层 Mailbox 硬件 中断通知、状态同步

RPMsg的消息格式是固定的,我贴一个简化版的结构体:

struct rpmsg_hdr {
    u32 src;      // 源端点地址
    u32 dst;      // 目标端点地址
    u32 len;      // 数据长度
    u16 flags;    // 标志位
    u16 reserved; // 保留
    u8  data[];   // 实际数据
} __packed;

每个消息都带源和目标端点,这样多个应用可以复用同一个物理通道。比如音频应用用端点1,传感器用端点2,互不干扰。

注意:RPMsg本身不保证实时性。如果你需要硬实时通信(比如电机控制),建议在从核侧用裸机驱动直接操作Mailbox,绕过Linux的调度延迟。

1.4 应用场景分析

我这些年接触过的项目,RPMsg+Mailbox的组合主要用在以下几个场景:

  • 车载信息娱乐系统:A核跑Android做UI,M核跑AUTOSAR做CAN通信。RPMsg传递车辆状态和触控指令。
  • 无人机飞控:A核跑视觉SLAM,M核跑姿态控制。Mailbox传递控制指令,共享内存传图像数据。
  • 工业PLC:A核跑EtherCAT主站协议栈,M核跑IO扫描。RPMsg做配置下发和状态上报。
  • 智能音箱:A核跑语音识别,DSP核做降噪和唤醒。RPMsg传递音频流和唤醒事件。

我印象最深的是做无人机项目时,一开始用Mailbox直接传控制数据,每次只传4字节。后来发现RPMsg的通道管理太方便了——一个通道传姿态,一个通道传GPS,一个通道传调试日志。代码结构清晰多了。

选型建议:如果你的系统满足以下条件,RPMsg是首选方案:

  • 主核运行Linux
  • 从核运行RTOS或裸机
  • 通信数据量在几十字节到几KB之间
  • 需要支持多个通信通道

如果只是简单的状态同步(比如心跳、唤醒),直接用Mailbox裸寄存器就够了,别上RPMsg——杀鸡焉用牛刀。

好了,这一章的内容就到这里。Mailbox和RPMsg的关系,你可以理解为:Mailbox是信使,RPMsg是信封。信使负责跑腿,信封规定了地址和格式。两者配合,异构多核才能高效协作。