0. 起因
之前在RPC原理与FastRPC实现一文中介绍过RPC的原理,简而言之,RPC就是实现本地程序调用位于另一个地址空间的例程(routine)的一种技术手段,其基本架构如图0-1所示。
由于RPC只是一种技术手段,并没有一个统一的标准,因此,每一种RPC框架根据其应用场景不同,所采用的实现方式也不尽相同。这些差异主要集中在两个方面:
- 数据的序列化和反序列化方法不同:例如可以使用JSON、XML以及谷歌推出的Protocol Buffer、Flat Buffer等格式作为数据传递格式,甚至是自己定义的一套格式;
- 数据传递方法不一样:例如可以通过HTTP、TCP等网络协议栈将数据发送出去。
今天主要介绍的是众多数据传递方式中的一种——RPMsg。
RPMsg,全称Remote Processor Messaging,它定义了异构多核处理系统(AMP,Asymmetric Multiprocessing)中核与核之间进行通信时所使用的标准二进制接口。
1. AMP
现在的芯片非常复杂,很多都是包含多个核,特别是片上系统(SoC),一颗芯片上不仅包含了很多个核心,并且很多核心都是异构的。例如手机里的芯片,就可能包含了CPU、GPU、DSP等不同的处理器单元。显然,这些不同架构的核心都有着他们各自的目的,例如,为了在端测实现高效的神经网络模型推理,现在的高端手机芯片基本都搭载了专门为神经网络这种密集计算的算法定制的运算单元。既然是不同单元,我们就不能等同的对待他们。
为了最大限度的发挥他们的性能,协同完成某一任务,不同的核心上面运行的系统可能各不相同,有些核心上面运行的通用系统例如Linux、Android等,另外一些核心上可能运行的就是实时操作系统(RTOS)等。这些不同架构的核心以及他们上面所运行的软件组合在一起,就成了异构多处理系统(Asymmetric Multiprocessing System)。
由于一般他们存在的目的都是协同的处理事情,因此在异构多处理系统中往往会形成主-从(Master-Slave)结构。主核上的系统先启动,并负责准备好运行环境,然后根据需要或者一定规则启动从核并对其进行管理。主-从核心上的系统都准备好之后,他们之间就通过IPC(Inter Processor Communication)方式进行通信,而RPMsg就是IPC中的一种。对于非通用的操作系统,它上面很可能是没有搭载传统的TCP/IP协议栈的,因此,当主核想要通过RPC的方式调用从核上的服务的时候,便不能使用一般的RPC框架所采用的网络通信方式。这时候类似于RPMsg这种专门用于核间通信的通信协议就派上了用场。
2. RPMsg
2.1. Linux中的RPMsg
在Linux内核代码中,RPMsg的代码主要位于drivers/rpmsg/下,文件之间的主要关系如图2-1所示。一开始Linux中只使用VirtIO作为该协议传输层,后来又增加了Glink、SMD等,Glink和SMD主要用于高通平台。
用户代码通过操纵rpmsg驱动,实现数据的收发操作。所有数据都在RPMsg总线上传递。
2.2. 原理
在AMP系统中,主-从核心通过共享内存的方式进行通信,如图2-2所示。内存的管理由主核负责,在每个通信方向上都有两个缓冲区,分别是USED和AVAIL,这个缓冲区可以按照RPMsg中消息的格式分成一块一块链接形成一个环,如图2-3所示。