芯片里的「信箱」:一个决定了核间通信效率的小东西
你有没有想过,一个芯片里两个 CPU 核之间是怎么「说话」的?
它们又不能喊话,也没有微信。
答案很简单——信箱。芯片设计者管它叫 Mailbox。
最早是「传纸条」
芯片刚刚进入多核时代那会儿,两个核想通信,最粗暴的办法是:共享一段内存,然后互相轮询。
Core 0 往地址 0x8000 写一段数据,Core 1 每秒来看一万次——「有新的吗?有新的吗?有新的吗?」
这是最早的核间通信:轮询(Polling)。
效率嘛,你可以想象一下两个人传纸条,但收件人每秒钟打开信箱看 10000 次。绝大部分时候信箱是空的,CPU 时间全浪费在读空地址上。
你说,加个中断通知不就行了?
对,这就是 Mailbox 的诞生。
Mailbox 到底长什么样
芯片里的 mailbox,和你家门口那个铁皮箱子本质上是一回事。
它有:
- 一个或几个数据寄存器——你能往里丢数据(就像投信)
- 一个状态寄存器——告诉对方「信箱里有信了」
- 一个门铃信号(Doorbell)——叮咚,来新消息了
Core 0 写数据,按门铃。Core 1 收到中断,来取信。
就这么简单。
一个完整通信只需要三次寄存器操作 + 一次中断,延迟通常在几百纳秒到几微秒之间。
为什么不用共享内存算了?
你可能会想:大家共用一块内存,写个标志位不就行了?
确实可以,但有几个坑:
- 缓存一致性(Cache Coherency)——Core 0 写了内存,但数据还躺在 L1 cache 里,Core 1 读到的可能是脏数据。你总得加 cache flush 或者用 uncached 内存,一个 flush 就要几十个周期。
- 没有硬件排队——如果两个核同时写同一个地址,谁先谁后?你得用自旋锁、原子操作,每多一个核参与,复杂度指数级上升。
- 没有标准的中断机制——Core 0 写了数据,Core 1 怎么知道?要么轮询,要么自己搭中断逻辑。
Mailbox 用硬件把这些全包了:硬件保证原子性、带中断通知、寄存器访问天然跨 cache 域。
实际干啥用?
举几个真实的例子。
AMP 系统(非对称多核)是最常见的场景。一块 SoC 里,一个 Cortex-A 核跑 Linux,一个 Cortex-M 核跑裸机或 RTOS。
M 核控制电机,A 核要给 M 核发指令:「把风扇转速调到 3000 RPM」。
A 核把「3000」写进 mailbox,M 核收到中断,读数据,调速,再往 mailbox 回写「OK」。
全程不需要碰共享内存,不需要同步锁。
这就是 RPMsg(Remote Processor Messaging) 的底层工作方式。TI 的 OMAP、NXP 的 i.MX 系列都在用。
电源管理也是重头戏。CPU 要睡眠了,通过 mailbox 给 PMU(电源管理单元)发个消息:「我要睡了,电压降到 0.8V」。PMU 搞定后回个「好了,睡吧」。
比你自己写 GPIO 电平来握手、还得用定时器做超时退出的方案,优雅一万倍。
还有安全岛(Safety Island)。主核把关键的安全数据发给独立的监控核,监控核做完 CRC 校验,确认没问题才放行。这个过程要是出了差错,那就是车规级的事故。
Mailbox 在这里的角色是:一个带硬件保证的保险通道。
它也有脾气
Mailbox 不是万能的。
最蛋疼的问题是深度有限。大多数 mailbox 只有 1~4 个槽位,满了就堵。你往里写,要么返回 busy,要么直接丢掉。
上层协议(比如 RPMsg)会在共享内存里做一个环形缓冲区(vring),mailbox 只负责发「有数据了」的信号。这样数据量再大也不怕——mailbox 只是一个门铃。
另一个问题是没有标准化。ARM 出了一个 MHU(Message Handling Unit)规范,但各家 SoC 的 mailbox 寄存器布局千奇百怪。Linux 内核里有一个 mailbox 子系统,但底层的 driver 还是得每家自己写。
一个小尾巴
Mailbox 不是什么炫酷的技术。没有 AI 加速器那种「每秒多少 TOPS」的卖点,没有高速 SerDes 那种「跑多少 Gbps」的性感。
但它是最早让芯片里的「大脑们」学会协作的小玩意。
一个 SoC 里十几个不同的处理器——CPU、GPU、NPU、DSP、ISP、安全核——它们能有序地分工、传递消息、同步状态,靠的往往就是几组 mailbox 寄存器和一声门铃。
有时候,最简单的东西反而是最优雅的。
评论