0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

多核异构通信框架(RPMsg-Lite)

Rice嵌入式开发技术分享 来源:Rice嵌入式 作者:Rice嵌入式 2024-03-08 18:20 次阅读

概要

随着科技的飞速发展,计算需求日益复杂和多样化,传统的单核处理器已难以满足所有应用场景的需求。在这样的背景下,异构多核系统应运而生,成为推动计算领域进步的重要力量。异构多核系统不仅提高了计算效率,还优化了能耗,为众多领域带来了革命性的变革。

异构多核系统是指在一个芯片上集成多种不同类型的处理器核心,这些核心可能采用不同的指令集架构(ISA),具备不同的性能特性和功耗要求。这些核心可以是高性能的通用处理器核心,也可以是专为特定任务设计的专用核心,如图形处理单元(GPU)、数字信号处理器(DSP)或神经网络处理器(NPU)等。

异构多核系统的特点主要体现在以下几个方面:

性能提升:通过结合不同类型的处理器核心,异构多核系统能够充分发挥各核心的优势,实现计算性能的大幅提升。例如,高性能核心可以处理复杂的计算任务,而专用核心则可以加速特定类型的数据处理。

能效优化:异构多核系统能够根据任务需求动态调整核心的使用,避免资源浪费和不必要的功耗。对于计算密集型任务,可以使用高性能核心;而对于数据密集型任务,则可以利用专用核心进行高效的数据处理,从而实现能效比的最大化。

灵活性:异构多核系统能够适应多样化的应用场景,通过灵活的任务调度和核心分配,满足不同任务的需求。这使得系统能够同时处理多种类型的任务,提高整体计算效率。

并行处理:不同类型的核心可以并行工作,实现任务级别的并行处理。这种并行性可以进一步提高系统的整体性能,缩短计算时间。

多核通信

市面目前多核异构芯片形态:

形态 型号 核心组成 方案
ARM MCU系列 STM32H747XIH6U ARM Cortex-M7 + ARM Cortex-M4 RTOS(裸机) + RTOS(裸机)
ARM MPU系列 RK3568 四核 ARM Cortex-A55 1. 核心0:Linux + 核心1~3:RTOS(裸机)
2. 核心0~2(SMP):Linux + 核心3:RTOS(裸机)
ARM MPU系列 + ARM MCU系列 STM32MP157 双核ARM Cortex-A7 + ARM Cortex-M4 双核ARM Cortex-A7:Linux(RTOS) + ARM Cortex-M4:RTOS(裸机)
ARM MPU系列 + RISC-V系列 V853 ARM Cortex-A7 + RISC-V ARM Cortex-A7:Linux(RTOS) + RISC-V:RTOS(裸机)
RISC-V系列 + DSP系列 + ARM MCU系列 R128 RISC-V + HiFi5 DSP + ARM M33 RISC-V:RTOS + HiFi5 DSP:裸机 + ARM M33:RTOS

由于异构多核系统中集成了多种不同类型的处理器核心,这些核心之间需要进行高效的数据通信和协同工作,以确保整体系统的性能和稳定性。因此,通信机制在异构多核系统中扮演着至关重要的角色。为了确保核心间的顺畅通信,异构多核系统采用了多种通信协议和接口技术,如共享内存、消息传递接口(MPI)、高级可扩展接口(AEI)等。这些通信机制使得不同核心之间能够快速地传输数据、共享资源和协同执行任务,从而实现整体系统的高效运行。

异构多处理系统中往往会形成主-从(Master-Remote)结构。主核上的系统先启动,并负责准备好运行环境,然后根据需要或者一定规则启动从核并对其进行管理。主-从核心上的系统都准备好之后,他们之间就通过 IPC(Inter Processor Communication)方式进行通信,而 RPMsg 就是 IPC 中的一种。RPMsg,全称 Remote Processor Messaging,它定义了异构多核处理系统(AMP,Asymmetric Multiprocessing)中核与核之间进行通信时所使用的标准二进制接口。

76f33bc0-da88-11ee-b759-92fbcf53809c.jpg

常见的多核通信框架:OpenAMP, RPMsg,rpmsg-lite等,本片文章的主角是:rpmsg-lite

RPMsg-Lite介绍

RPMsg-Lite组件,它是远程处理器消息传递 (RPMsg) 协议的轻量级实现。RPMsg 协议定义了一个标准化的二进制接口,用于在异构多核系统中的多个核之间进行通信。与开放非对称多处理 (OpenAMP) 框架(https://github.com/OpenAMP/open-amp)的 RPMsg 实现相比,RPMsg-Lite 减少了代码大小、简化了 API 并改进了模块化。在较小的基于 Cortex-M0+ 的系统上,建议使用 RPMsg-Lite。RPMsg-Lite 是由 NXP Semiconductors 开发的开源组件,并在 BSD 兼容许可下发布。

RPMsg-Lite官方仓库:https://github.com/nxp-mcuxpresso/rpmsg-lite

RPMsg-Lite官方文档:https://nxp-mcuxpresso.github.io/rpmsg-lite

RPMsg-Lite源码目录:

.
├──common
│└──llist.c
├──include
│├──environment
││└──rt-thread
││└──rpmsg_env_specific.h
│├──llist.h
│├──platform
││└──RK3568
││├──rpmsg_config.h
││└──rpmsg_platform.h
│├──rpmsg_compiler.h
│├──rpmsg_default_config.h
│├──rpmsg_env.h
│├──rpmsg_lite.h
│├──rpmsg_ns.h
│├──rpmsg_queue.h
│├──virtio_ring.h
│└──virtqueue.h
├──rpmsg_lite
│├──porting
││├──environment
│││└──rpmsg_env_threadx.c
││└──platform
││└──RK3568
││└──rpmsg_platform.c
│├──rpmsg_lite.c
│├──rpmsg_ns.c
│└──rpmsg_queue.c
└──virtio
└──virtqueue.c

创建目的

开发RPMsg-Lite的原因有多种:①是需要与RPMsg协议兼容的通信组件占用空间小;②是OpenAMP RPMsg实现的广泛API的简化。RPMsg协议没有记录,其唯一定义是由Linux内核和旧版OpenAMP实现给出的。这已经随着基于无锁共享内存的多核通信协议的出现而改变,它是一个标准化协议,允许多种不同的实现共存并且仍然相互兼容。

基于小型MC 的系统通常不实现动态内存分配。RPMsg-Lite中静态API的创建进一步减少了资源使用。动态分配不仅会额外增加5KB的代码大小,而且通信速度会变慢且确定性较差,这是动态内存引入的一个特性。下表显示了OpenAMP RPMsg实现和新RPMsg-Lite实现之间的一些粗略比较数据:

组件/配置 Flash[B] RAM[B]
OpenAMP RPMsg / Release (reference) 5547 456 + dynamic
RPMsg-Lite / Dynamic API, Release 3462 56 + dynamic
Relative Difference [%] ~62.4% ~12.3%
RPMsg-Lite / Static API (no malloc), Release 2926 352
Relative Difference [%] ~52.7% ~77.2%

框架说明

RPMsg-Lite的实现可以分为三个子组件。核心组件位于rpmsg_lite.c中。其中rpmsg_ns.c和rpmsg_queue.c是可选的,两个可选组件用于实现阻塞接收API(在rpmsg_queue.c中和动态“命名”端点创建和删除公告服务(在rpmsg_ns.c中)。

实际的“媒体访问”层在virtqueue.c中实现,它是与 OpenAMP 实现共享的少数文件之一。该层主要定义了共享内存模型,内部定义了vring或者virtqueue等用到的组件。

移植层分为两个子层:环境层和平台层。第一个子层将针对每个环境单独实现。(裸机环境已经存在并在rpmsg_env_bm.c中实现,FreeRTOS 环境在rpmsg_env_freertos.c等中实现)只有与所使用的环境匹配的源文件才会包含在目标应用程序项目中。第二个子层在rpmsg_platform.c中实现,主要定义中断启用、禁用和触发的低级函数。情况如下图描述:

76fc9bf2-da88-11ee-b759-92fbcf53809c.jpg

核心子组件

该子组件实现了阻塞发送 API 和基于回调的接收 API。RPMsg 协议是传输层的一部分。这是通过使用所谓的端点来实现的。每个端点可以分配不同的接收回调函数。然而,需要注意的是,在当前的设计中,回调是在中断环境中执行的。因此,不鼓励在回调中执行某些操作(例如内存分配)。下图显示了 RPMsg 在类 ISO/OSI 分层模型中的作用:

76f33bc0-da88-11ee-b759-92fbcf53809c.jpg

队列子组件(可选):该子组件是可选的,需要在环境移植层中实现env_*_queue()函数。它使用阻塞接收API,这在RTOS环境中很常见。它支持复制和非复制阻塞接收功能。

名称服务子组件(可选):该子组件是RPMsg的Linux内核实现中存在的名称服务的最小实现。它允许通信节点发送有关“命名”端点(即通道)创建或删除的公告,并在应用程序回调中采取任何用户定义的操作来接收这些公告。用于接收名称服务公告的端点地址被任意固定为53(0x35)。

应用

应用程序应将 /rpmsg_lite/lib/include 目录放入包含路径,并在应用程序中包含rpmsg_lite.h头文件,或者选择包含rpmsg_queue.h和/或rpmsg_ns.h文件。RPMsg-Lite提供两个移植子层,但如果计划使用其他的RTOS,您需要实现其他RTOS的环境层(例如,rpmsg_env_xxxrtos.c)并将其包含在项目构建中。

堆栈的初始化是通过调用主端的rpmsg_lite_master_init()和远程端的rpmsg_lite_remote_init()来完成的。该初始化函数必须在任何RPMsg-Lite API调用之前调用。在init之后,需要创建一个通信端点,否则通信是不可能的。通过调用rpmsg_lite_create_ept()函数来完成。可以选择接受最后一个参数,在该参数中创建端点的内部上下文,以防RL_USE_STATIC_API选项设置为1。如果不是,堆栈将在内部调用env_alloc()为其分配动态内存。如果要使用基于回调的接收,则使用用户定义的回调数据指针将ISR回调注册到每个新端点。如果需要阻塞接收(在 RTOS 环境的情况下),则必须在调用rpmsg_lite_create_ept()之前调用rpmsg_queue_create()函数。队列句柄作为回调数据参数传递给端点创建函数,并且回调函数设置为rpmsg_queue_rx_cb()。然后可以使用 rpmsg_queue_receive() 函数在队列对象上侦听传入消息。rpmsg_lite_send()函数用于向对方发送消息。

RPMsg-Lite 还为发送和接收操作实现无复制机制。这些方法需要在应用程序中使用时必须考虑的细节。

无复制发送机制:该机制允许发送消息,而无需将数据从应用程序缓冲区复制到共享内存中的 RPMsg/virtio 缓冲区。要执行的无复制发送步骤的顺序如下:

调用rpmsg_lite_alloc_tx_buffer()函数获取virtio缓冲区并将缓冲区指针提供给应用程序。

将要发送的数据填充到预先分配的virtio缓冲区中。确保填充的数据不超过缓冲区大小(作为rpmsg_lite_alloc_tx_buffer()大小输出参数提供)。

调用rpmsg_lite_send_nocopy()函数将消息发送到目标端点。考虑缓存功能和virtio缓冲区对齐。

no-copy-receive机制:该机制允许读取消息,而无需将数据从共享内存中的virtio缓冲区复制到应用程序缓冲区。要执行的无复制接收步骤的顺序如下:

调用rpmsg_queue_recv_nocopy()函数获取指向接收数据的virtio缓冲区指针。

直接从共享内存中读取接收到的数据。

调用rpmsg_queue_nocopy_free()函数释放virtio缓冲区并使其可用于下一次数据传输。

用户有责任在取消初始化时销毁他创建的任何RPMsg-Lite对象。为此,函数rpmsg_queue_destroy()用于销毁队列,rpmsg_lite_destroy_ept()用于销毁端点,最后,rpmsg_lite_deinit()用于取消初始化RPMsg-Lite核间通信堆栈。在取消初始化队列之前,使用队列取消初始化所有端点。否则,您将主动使已使用的队列句柄失效,这是不允许的。RPMsg-Lite不会在内部检查这一点,因为它的主要目标是轻量级。

77167658-da88-11ee-b759-92fbcf53809c.png

配置选项

RPMsg-Lite可以在编译时进行配置。默认配置在rpmsg_default_config.h头文件中定义。用户可以通过包含具有自定义设置的rpmsg_config.h文件来自定义此配置。下表总结了所有可能的 RPMsg-Lite 配置选项。

配置选项 默认值 用法
RL_MS_PER_INTERVAL (1) 用于轮询的非阻塞 API 函数中使用的延迟(以毫秒为单位)。
RL_BUFFER_PAYLOAD_SIZE (496) 缓冲区有效负载的大小,它必须等于 (240, 496, 1008, ...) [2^n - 16]
RL_BUFFER_COUNT (2) 缓冲区的数量,必须是 2 的幂 (2, 4, ...)
RL_API_HAS_ZEROCOPY (1) 启用/禁用零复制 API 函数。
RL_USE_STATIC_API (0) 启用/禁用静态 API 函数(无动态分配)。
RL_CLEAR_USED_BUFFERS (0) 在返回到启用/禁用的空闲缓冲区池之前清除已使用的缓冲区。
RL_USE_MCMGR_IPC_ISR_HANDLER (0) 当启用时,IPC 中断由多核管理器(IPC 中断路由器)管理;当禁用时,RPMsg-Lite 自行管理 IPC 中断。
RL_USE_ENVIRONMENT_CONTEXT (0) 启用后,环境层使用自己的上下文。某些环境需要 (QNX)。默认值为 0(无上下文,节省一些 RAM)。
RL_DEBUG_CHECK_BUFFERS (0) 启用后,将检查传递给rpmsg_lite_send_nocopy()和rpmsg_lite_release_rx_buffer()函数(由 RL_API_HAS_ZEROCOPY 配置启用)的缓冲区指针,以避免传递无效的缓冲区指针。默认值为 0(禁用)。请勿在 RPMsg-Lite 到 Linux 配置中使用。
RL_ALLOW_CONSUMED_BUFFERS_NOTIFICATION (0) 启用后,每次接收到的缓冲区被消耗并放入可用缓冲区队列时,都会通知对方。在 RPMsg-Lite 到 Linux 配置中启用此选项,以允许解除 Linux 阻塞发送的阻塞。默认值为 0(RPMsg-Lite 到 RPMsg-Lite 通信)。
RL_ALLOW_CUSTOM_SHMEM_CONFIG (0) 它允许定义自定义共享内存配置并替换 rpmsg_config.h 中与共享内存相关的全局设置。当多个实例并行运行但需要不同的共享内存排列(vring 大小和对齐、缓冲区大小和计数)时,这非常有用。默认值为 0(所有 RPMsg_Lite 实例使用由公共配置宏定义的相同共享内存排列)。
RL_ASSERT 请参阅rpmsg_default_config.h 断言实施。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 芯片
    +关注

    关注

    451

    文章

    49725

    浏览量

    417669
  • 异构
    +关注

    关注

    0

    文章

    37

    浏览量

    13007
  • 多核系统
    +关注

    关注

    0

    文章

    11

    浏览量

    7468
收藏 人收藏

    评论

    相关推荐

    多核异构中A核与M核通信过程

    目前域控项目有的采用S32G这类多核异构的芯片,转载一篇分析下多核异构中A核与M核通信过程的文章。
    的头像 发表于 10-31 11:09 942次阅读
    <b class='flag-5'>多核</b><b class='flag-5'>异构</b>中A核与M核<b class='flag-5'>通信</b>过程

    【米尔-TIAM62开发板-接替335x-试用评测】4、异构通信初体验

    我们在前面的文章有提到过Linux的remoteproc框架,并通过它体验了一番异构核心的控制和运行,这一次我们来体验一下异构核心通信。 1、RPM
    发表于 01-05 20:30

    AvaotaA1全志T527开发板AMP异构计算简介

    标准的 RPMsg 驱动框架,小核心是基于 OpenAMP 的异构通信框架。 AMP 与 RPMsg
    发表于 07-24 09:54

    【米尔NXP i.MX 93开发板试用评测】2、异构通信环境搭建和源码编译

    rpmsg-lite进行通信rpmsg-lite是一个轻量级的远程过程调用(RPC)库,用于在不同的处理器核心之间进行高效的数据传输。 在正常编译前,需要先解压缩arm-none-eabi-gcc,并且将
    发表于 09-20 23:19

    【米尔NXP i.MX 93开发板试用评测】1、异构核心通信的技术内容

    RPMsg-Lite是Remote Processor Messaging (RPMsg)协议的轻量级实现。RPMsg协议定义了一个标准化的二进制接口,用于异构
    发表于 09-21 20:24

    创龙带您解密TI、Xilinx异构多核SoC处理器核间通讯

    进行控制操作和多媒体显示;DSP天生为数字信号处理而生,擅长进行专用算法运算;FPGA擅长高速、多通道数据采集和信号传输。同时,异构多核SoC处理器核间通过各种通信方式,快速进行数据的传输和共享,可完美实现
    发表于 09-08 09:39

    MPU进化,多核异构处理器有多强?

    CoreB 传递消息的过程,反之亦然。二、驱动层Virtio下RPMsg通信实现Virtio是通用的IO虚拟化模型,位于设备之上的抽象层,负责前后端之间的通知机制和控制流程,为异构多核
    发表于 11-21 09:45

    A核+M核通信过程解析

    消息的过程,反之亦然。二、驱动层Virtio下RPMsg通信实现Virtio是通用的IO虚拟化模型,位于设备之上的抽象层,负责前后端之间的通知机制和控制流程,为异构多核间数据
    发表于 11-23 15:09

    是否有不使用FreeRTOS的RPMSG示例?

    我正在使用 iMX8MPlus。我已经构建/运行了rpmsg_lite_str_echo_rtos示例并设法从 Linux 与它通信;但是,我不想让 FreeRTOS 挡路。是否有不使用 FreeRTOS 的 RPMSG 示例?
    发表于 04-20 07:50

    嵌入式异构多核的片上通信架构设计

    为了克服目前嵌入式异构多核处理器的片上通信架构无法提供高效的异构多核协作架构的问题,本文分析了嵌入式异构
    发表于 12-04 11:30 26次下载

    基于SystemC的异构多核通信模块设计

    通过分析异构多核体系中片上处理核的核间通信,采用共享存储区实现多核间的通信和数据共享,并提出一种处理器与总线之间添加
    发表于 01-20 15:01 10次下载

    基于SystemC的异构多核通信模块设计

    通过分析异构多核体系中片上处理核的核间通信,采用共享存储区实现多核间的通信和数据共享,并提出一种处理器与总线之间添加
    发表于 07-17 16:51 19次下载

    使用OpenAMP多核框架来满足控制和通信要求

      该框架的一个实例在每个核心上运行。使用Remoteproc提供生命周期管理,其中一个核心被指定为“主”。内核间通信使用RPMsg进行管理,RPMsg在内核之间提供基于通道的双向
    的头像 发表于 07-01 10:04 1.1w次阅读
    使用OpenAMP<b class='flag-5'>多核</b><b class='flag-5'>框架</b>来满足控制和<b class='flag-5'>通信</b>要求

    使用多核处理器适用于智能产品设计方案

    在任何多核计算环境中,单独的处理器都需要有效的机制来传递请求和共享数据。对于 i.MX 8M Mini EVK 应用,NXP 使用的是 RPMsg-Lite——远程处理器消息传递 (RPMsg) 协议的精简版。
    发表于 08-02 10:40 1428次阅读
    使用<b class='flag-5'>多核</b>处理器适用于智能产品设计方案

    YY3568多核异构(Linux+RT-Thread)--启动流程

    概要 上一篇文章,介绍了多核异构的方案,RPmsg-lite多核通信框架的内容。--《
    的头像 发表于 03-07 08:41 1577次阅读
    YY3568<b class='flag-5'>多核</b><b class='flag-5'>异构</b>(Linux+RT-Thread)--启动流程