RPMsg是一个多核通信栈,已经在FreeRTOS BSP里集成了,可用于与i.MX A7和M4核进行通讯。这个协议栈来源于github上的一个开源项目OpenAMP (see http://github.com/OpenAMP/open-amp) 除了RPMsg API,这个版本中没有包含OpenAMP的其他特性. 远程处理器消息传递(RPMsg)是一种基于virtio的消息传递总线,允许在非对称多处理(AMP)系统中存在的同构或异构核上运行的独立软件上下文之间的处理器间通信(IPC)。RPMsg组件源代码最近作为开放式非对称多处理(OpenAMP)框架的一部分发布.RPMsg API符合上游Linux3.4.x内核中存在的RPMsg总线基础结构。 原始RPMsgAPI基于通过已注册的接收回调处理中断上下文中的传输数据(消息),该回调在接收到消息时被调用。 这种方法的不便之处在于,接收数据的所有处理必须在中断上下文中完成,或者必须将消息复制到临时应用程序缓冲区中以供以后处理。 可用API的两种用法都与实时操作系统(RTOS)的概念不兼容,因为中断总是抢占正在运行的任务,无论其当前优先级如何,并且这种中断可以在随机日期发生并且可以
采取随机的执行时间。这可能会在实时系统时序中引入额外的抖动。此外,使用RTOS进行应用程序开发的做法是拥有多个独立的顺序上下文。 拥有阻塞顺序API更自然,更方便,原始RPMsgAPI中没有。 阻塞API的一个很好的例子是套接字接口或任何类似POSIX的接口。 因此,自然趋势是为应用程序员提供这种接口。 总而言之,RPMsgAPI的RTOS感知扩展的优点如下: •中断上下文中无数据处理 •阻塞式接收API •零拷贝发送和接收API •允许由RTOS提供的超时接收 •与LinuxOS上游兼容 恩智浦对RPMsg的贡献包括在原始基础RPMsg层之上创建的两个附加层: RPMsg扩展层允许用户分配和释放virtio tx缓冲区,以及实现零拷贝发送功能。 RPMsg扩展层API旨在用于裸机应用程序。 RPMsg RTOS层解决了上面讨论的基于RTOS的应用程序需求(处理中断上下文之外的接收数据,阻塞接收API实现,零复制机制)。 这个支持RTOS的RPMsg API层分为多个C模块: rpmsg_rtos.c/.h包含一个通用实现,它不依赖于使用的RTOS,也不依赖于使用的平台。 在 /porting/<device>/platform.c/.h 和platform_info.c中,是依赖于平台(SoC)的功能。 在 /porting/env/<rtos name>/rpmsg_porting.c/.h中,RTOS的抽象是使用platform.h中的函数实现的,以便与硬件建立连接。但是,rpmsg_porting.c/.h 模块本身与硬件无关。
要访问RPMsg RTOS层API,必须在应用程序C模块(即main.c)中包含rpmsg_rtos.h文件。在RTOS启动之后,用户应该调用rpmsg_rtos_init()函数来初始化RPMsg并与对方(其他核心)同步。 在此之后,可以通过调用rpmsg_rtos_create_ept()在任意RTOS线程中创建应用程序端点。 rpmsg_rtos_send()函数用于将数据从端点发送到远程端点,远程端点地址在函数调用中指定。 然后,rpmsg_rtos_recv()用于接收端点上的数据或等待以特定超时接收数据(或者可以将超时设置为永久等待)。 如果应用程序内存不足或需要更高内存效率和更快,则可以使用无复制机制。RPMsg RTOS层实现了发送和接收操作的无复制机制。在应用程序中使用时必须考虑细节。 无复制发送机制:这种机制允许发送消息而无需将数据从应用程序缓冲区复制到共享内存中的RPMsg/virtio缓冲区。要执行的发送步骤如下: •调用rpmsg_rtos_alloc_tx_buffer()函数以获取virtio缓冲区并提供指向应用程序的缓冲区指针。 •填写要发送到预分配的virtio缓冲区的数据。确保填充的数据不超过缓冲区大小(以rpmsg_rtos_alloc_tx_buffer()大小输出参数的形式提供)。 •调用rpmsg_rtos_send_nocopy()函数将消息发送到目标端点。缓存功能和virtio缓冲区对齐问题请参阅rpmsg_rtos_send_nocopy()。 无复制接收机制:此机制允许直接读取消息,而无需将数据从共享内存中的virtio缓冲区复制到应用程序缓冲区。要执行的无复制接收步骤的顺序如下: •调用rpmsg_rtos_recv_nocopy()函数以获取指向接收数据的virtio缓冲区指针。 •直接从共享存储器读取接收的数据。 •调用rpmsg_rtos_recv_nocopy_free()函数以释放virtio缓冲区并使其可用于下一次数据传输。
|