时间轴
时间轴
2026-07-02
init
本文介绍了STM32MP157中IPCC(进程间通信控制器)硬件模块的工作原理,讨论了其通过共享内存和硬件中断机制实现Cortex-A7与Cortex-M4核间信号通知的过程,并总结了IPCC的通道分配、软件框架应用及相关寄存器的配置。
IPC( Inter -Process Communication,进程间通信)是指两个进程(广义的进程间,包括异构核心的进程)的数据之间发生交互,它是通过处理器间通信控制器 IPCC(Inter-Process Communication controller ,IPC 控制器)来实现的,IPCC属于硬件部分,用于在两个CPU之间进行信号交换,邮箱依赖于IPCC,STM32MP157的 IPCC 硬件模块有 6 个双向通道,每个通道分为两个子通道,6 个双向通道则共有 12 个子通道。如图所示是 A7 内核和 M4 内核通过 IPCC 进行通信的结构框图。

当一个数据包被放入共享内存时,CPU 需要中断或“通知”另一个 CPU 有新的数据包在共享内存中要处理,另外一个 CPU 收到信号后就去处理了,这是使用 IPCC 硬件中断机制来完成的。
A7 内核的中断控制器是 GIC,M4 内核的中断控制器是 NVIC。IPCC 的作用就好比放哨员,什么时候有数据可以接收,什么时候可以发送数据,整个过程是由 IPCC 来控制的。
IPCC只是提供了处理器之间信息交换的机制,它并不具有数据传输功能,也就是说,处理器之间要交互的数据并不是在 IPCC 中传输的,是在共享内存中传输的。
IPCC 通道
IPCC 的 6 个通信的工作模式可分为单工、半双工和全双工:
- 从 CPU1 到 CPU2 的方向有 6 个通道(P1_TO_P2 子通道,P1 代表 CPU1,P2 代表CPU2)
- 从 CPU2 到 CPU1 的方向有 6 个通道(P2_TO_P1 子通道,P1 代表 CPU1,P2 代表CPU2)
如下表所示,在 ST 官方配置的 IPCC 通信模型中,这 6 个通道被当做不同的软件框架来使用,其中:
- 通道 3 为单工模式,被当做 RemoteProc 框架,主处理器可通过该框架来加载协处理器的固件以及控制协处理器的生命周期;
- 通道 2 为全双工模式,被当做 RPMsg 框架,用于将 A7 的消息传输到 M4;
- 通道 1 为全双工模式,被当做 RPMsg 框架,用于将 M4 的消息传输到 A7。
| 通道 | 模式 | 用法 | 软件客户端框架:Cortex-A7(非安全) | 软件客户端框架:Cortex-M4 |
|---|---|---|---|---|
| 通道 1 | 全双工 | 从 Cortex-M4 到 Cortex-A7 的 RPMsg 传输: 1. Cortex-M4 使用该信道来指示一个消息可用 2. Cortex-A7 使用该信道以指示该消息被处理 | RPMsg 框架 | OpenAMP |
| 通道 2 | 全双工 | 从 Cortex-A7 到 Cortex-M4 的 RPMsg 传输: 1. Cortex-A7 使用该信道来指示一个消息可用 2. Cortex-M4 使用该信道以指示该消息被处理 | RPMsg 框架 | OpenAMP |
| 通道 3 | 单工 | Cortex-M4 关闭请求 | RemoteProc 框架 | CprocSync cube utility |
| 通道 4/5/6 | 未使用 |
单工通信: 指信号只在一个方向上传输,仅能发送或接收
半双工通信:信号可以在两个方向上传输,但某一个时刻只允许发送或接收(单总线和 I2C 都是半双工通信)
全双工通信:全双工通信指数据同时在两个方向上传输
可以看到,在ST配置好的框架中:
- RemoteProc软件框架解决了远程处理器生命周期的问题
- RPMsg软件框架解决了核间通信的问题
这两个就是在多核处理器通信中关心的问题!
在Linux内核下已经有ST移植好RemoteProc和RPMsg软件框架,在M4使用的OpenAMP库中也有对应的RemoteProc和RPMsg软件框架,M4主要依赖OpenAMP库中已有的软件框架来实现和A7通信。
注意: 为了便于主核能够控制协处理器,因此在linux端设计了OpenAMP框架,但是同时为了兼容linux端OpenAMP框架,M4的相关产商也设计了一个OpenAMP框架,两者是可对接的,但是还是有一定区别,但是名字一样
STM32MP157的A7和M4实际上是通过通道1和通道2来传递数据的:

IPCC 寄存器
和IPCC相关的8个寄存器,寄存器区被分成两个区域,每个处理器占用一个区域,防止读——写访问冲突,如下表中,前4个寄存器被处理器1占用,后4个寄存器被处理器2占用。
IPCC为处理器提供专用的中断,每个处理器都有自己的状态屏蔽寄存器位、每个通道的设置或清除寄存器位。
| 寄存器 | 说明 | 位(n表示1~6) |
|---|---|---|
| IPCC_C1CR | 使能/关闭 处理器1 TX通道空闲中断/RX通道占用中断 | TXFIE、RXOIE |
| IPCC_C1MR | 屏蔽/不屏蔽 处理器1 TX通道X空闲中断/RX通道X占用中断 | CHnFM、CHnOM |
| IPCC_C1SCR | 处理器1 TX/RX 通道X状态位 设置/清零 | CHnS、CHnC |
| IPCC_C1TOC2SR | 通道被占用/空闲 | CHnF |
| IPCC_C2CR | 使能/关闭 处理器2 TX通道空闲中断/RX通道占用中断 | TXFIE、RXOIE |
| IPCC_C2MR | 屏蔽/不屏蔽 处理器2 TX通道X空闲中断/RX通道X占用中断 | CHnFM、CHnOM |
| IPCC_C2SCR | 处理器2 TX/RX 通道X状态位 设置/清零 | CHnS、CHnC |
| IPCC_C2TOC1SR | 通道被占用/空闲 | CHnF |
IPCC_C1CR
IPCC 处理器1 控制寄存器
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | TXFIE |
| rw |
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | RXOIE |
| rw |
- 第17~ 31和第1~15位,保留位,必须保持在复位值。
- 第16位,TXFIE:处理器1发送(TX)通道 空闲中断 使能位,与 IPCC_C1TOC2SR关联,当该位为:
- 1:使能处理器1发送(TX)通道空闲中断;
- 0:关闭处理器1发送(TX)通道空闲中断。
- 第0位,RXOIE:处理器1接收(RX)通道占用中断使能位,与IPCC_C2TOC1SR关联,当该位为:
- 1:使能处理器1接收(RX)通道占用中断;
- 0:关闭处理器1接收(RX)通道占用中断。
IPCC_C1MR
IPCC 处理器1屏蔽寄存器
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | CH6FM | CH5FM | CH4FM | CH3FM | CH2FM | CH1FM |
| rw | rw | rw | rw | rw | rw |
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | CH6OM | CH5OM | CH4OM | CH3OM | CH2OM | CH1OM |
| rw | rw | rw | rw | rw | rw |
第22~ 31位和第6~15位,保留位,必须保持在复位值。
第16~ 21位,CH1FM~CH6FM,处理器1发送(TX)通道X空闲中断屏蔽位,与 IPCC_C1TOC2SR.CHxF关联,当该位为:
- 1:发送(TX)通道X空闲中断被屏蔽;
- 0:发送(TX)通道X空闲中断未被屏蔽。
第0,5位,CH1OMCH6OM,处理器1接收(RX)通道X占用中断屏蔽位,与IPCC_C2TOC1SR.CHxF相关,当该位为:
- 1:接收(RX)通道X占用中断被屏蔽;
- 0:接收(RX)通道X占用中断未被屏蔽。
IPCC_C1SCR
IPCC 处理器1 状态设置清除寄存器
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | CH6FM | CH5FM | CH4FM | CH3FM | CH2FM | CH1FM |
| rw | rw | rw | rw | rw | rw |
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Res | Res | Res | Res | Res | Res | Res | Res | Res | Res | CH6OM | CH5OM | CH4OM | CH3OM | CH2OM | CH1OM |
| rw | rw | rw | rw | rw | rw |
- 第22~ 31位和第6~15位,保留位,必须保持在复位值。
- 第16~ 21位,CH1S~CH6S,处理器1发送(TX)通道X状态设置位,与IPCC_C1TOC2SR.CHxF 相关,当设置该位:
- 1:处理器1发送(TX)通道X状态位被设置,即将CHnF设置为1,表示通道被占用;
- 0:无动作。
- 第0~ 5位,CH1C~CH6C,处理器1接收(RX)通道X状态清除位,与IPCC_C2TOC1SR.CHxF关联,当设置该位:
- 1:处理器1接收(RX)通道X状态位清零;
- 0:无动作
IPCC 功能描述
IPCC 对处理器通信的控制,其实是通过中断的方式来实现的,称为核间中断(IPI),在每个处理器上都有两条中断线,分别是:
- 一条用于 RX 通道占用(发送处理器发布数据);
- 一条用于TX通道空闲(接收处理器读取通信数据)。
每个通道都有中断屏蔽:
- 通道占用屏蔽(位 CHnOM);
- 通道空闲屏蔽(位CHnFM)。
在计算机、单片机或硬件外设(如 DMA、Mailbox、IPCC 等通信控制器)的上下文中,“屏蔽”(Mask)的意思是“关掉”或“过滤”掉某个中断信号,不让它上报给 CPU。
每个子通道都有两种工作模式:
- 单工模式(每个通道都有自己的通信数据存储位置);
- 半双工模式(与双向通信数据信息存储位置关联的单个通道)。
通信的数据位于共享内存中(注意,共享内存不是 IPCC 的一部分),每次通信,IPCC 模块提供一个通道状态标志位 CHnF(n 可取值 1~6,表示对应的通道):
- 当 CHnF=0 时,表示相关的通道是空闲的(也可以认为通信的数据已经被接收处理器读取了,此时通道处于空闲状态了),这个时候发送处理器可以占用这个通道用于发送数据;
- 当 CHnF=1 时,表示相关的通道已经被占用了(即通信数据已经被发送处理器发布了),这个时候接收处理器可以去访问该通道以读取数据。
IPCC 为通道管理提供非阻塞信令机制:
- 消息可用性中断;
- 通道流控制(如生成一个 TX 通道空闲中断,则称为流开启,当通道被占用时,则称为流关闭)。
应用程序受益于基于非阻塞中断的消息交换和通道流控制来进行核间通信,每个子通道会有一个传输方向:
- 从 CPU1 发送并由 CPU2 接收;
- 或者从 CPU2 发送并由 CPU1 接收。
单工发送模式
如下图所示为 IPCC 单工发送模式示意图。
- 当通道状态标志为通道占用时(CHnF=1),这是因为接收方没有从先前的消息中释放通道,这个时候,通道空闲中断被取消屏蔽,然后等待 TX 空闲中断。
- 一旦接收方释放了通道,就会产生通道空闲中断(流开启)。当产生通道空闲中断时,通道空闲中断被屏蔽,消息可以写入数据缓冲区。随后,通道状态标志被设置为已占用,这会触发接收端的通道占用中断。

单工接收模式
如下图所示为 IPCC 单工发送模式示意图。当产生通道占用中断时,接收端确定是哪个通道被占用,并屏蔽相应的通道占用中断,随后,可以从共享内存中读取数据,一旦读取数据,通道状态标志 CHnF 将被清除(CHnF=0),通道占用中断被取消屏蔽

半双工发送模式
如下图所示为 IPCC 半双工发送模式示意图。
半双工过程允许使用单个共享缓冲区将消息从发送方传输到接收方,然后将响应(Response pending)从接收方发送回发送方。
发送端发送数据过程:
- 软件变量 response pending=1 表示发送端等待接收端的应答
- response pending=0 表示获得接收端的应答。
首先,发送方检查通道状态标志,如果通道状态标志指示通道被占用(CHnF=1),即由于接收方尚未发送对先前消息的响应,则发送方等待响应,如果通道空闲,发送方可以将消息写入共享内存中。
随后,通道状态标志被设置为被占用,这会触发接收端的 RX 通道占用中断,一旦通道状态标志 CHnF=1,通道空闲中断被取消屏蔽。通道空闲中断表示接收方发送的响应是否可用,当产生通道空闲中断时(响应就绪),发送方确定释放哪个通道并屏蔽相应的通道空闲中断,随后,可以从共享内存中读取响应。
接收端的响应过程:
接收处理器等待软件变量 response pending 是否等于 1,如果等于 1,则接收端将响应写入共享内存中(发布响应),一旦发布了响应,通道状态标志 CHnF 被 CHnC 清除,则 CHnF 为 0,且接收端取消屏蔽通道占用中断(CHnOM = 0)。

半双工接收模式
如下图所示为 IPCC 半双工接收模式示意图。
- 接收端读取数据:当产生通道占用中断时,接收端判断哪个通道被占用,并屏蔽响应的通道占用中断,随后从共享内存中接收数据,只有在接收方将响应发送到共享内存中后,通道才会被释放。
- 发送端读取响应:为了接收响应,通道空闲中断被取消屏蔽,发送处理器会检查那个通道变为空闲,屏蔽相关的通道空闲中断,然后从共享内存中读取响应

IPCC 为 6 个双向通道提供了一种非阻塞信令机制,以原子方式发布和检索通信数据。非阻塞方式允许处理器以非阻塞的方式交换信息,例如读取数据,当不满足条件、未能立刻得到结果时,先挂起进程,然后每隔一段时间去检查是否满足条件了,若满足,则进行读取操作,若不满足,则不读取,这就是非阻塞方式。
以上描述的通信过程可以用如下图来表示,通信的处理器都可以访问共享的内存,围绕共享内存,从主处理器到协处理器以及从协处理器到主处理器的方向可以配置一根中断线,即内核间中断(PPI,简称核中断),核中断发起方首先将消息数据写到共享内存中,然后发起核间中断,被中断的核线程在中断服务程序中读取该共享内存,以获得发起方通知的数据。

Mailbox 框架
Mailbox(邮箱)框架和 IPCC 紧密联系,Mailbox 是一种驱动架构,它依赖于硬件平台来实现,例如,STM32MP157 平台的 Mailbox 依赖 IPCC 外设,其 Mailbox 框架如下图所示: (Mailbox算是一种消息传输的工具,底层依赖IPCC,但是IPCC不传输数据,Mailbox在基于IPCC的基础上可以进行消息数据的传递)

上层应用如何知道数据已经发送完毕或者已经接收完全了呢?这个工作就交给 Mailbox 框架来处理,Mailbox 的实现分为邮箱控制器(Mailbox contoller)和邮箱客户端(Mailbox client):
邮箱控制器主要负责配置和处理来自 IPCC 外设的消息队列或者中断请求(IRQ),并为负责发送或接收通知消息的邮箱客户端提供一个通用的 API。
邮箱客户端主要负责发送或接收通知消息,它通过邮箱控制器提供的通道来发送或接收通知消息,这个通道就是 IPCC 通道。
用户可以自己定义邮箱客户端,如上图 所示,Linux 下的邮箱控制器是stm32_ipcc,它配置和控制 IPCC 外设,可以提供邮箱服务。stm32_rproc是远程处理器平台 驱动程序 ,它主要处理与远程处理器关联的平台资源(例如寄存器、看门狗、复位、时钟和存储器),可将对应回调函数注册到 Remoteproc 框架中,还可以通过邮箱框架将通知消息转发到远程处理器。
邮箱框架的大概工作流程是:
- 先注册邮箱控制器;
- 邮箱客户端发送数据前,先申请通道;
- 客户端发送数据;
- 邮箱客户端记录数据;
- 邮箱控制器将底层接收到的数据回调给上层应用;
- 当数据发完时,邮箱控制器通知上层当前数据已经发送完成;
- 邮箱客户端释放通道。
关于 Mailbox 框架,在 Linux 内核源码drivers/mailbox目录下有相关的驱动。
