Lazy loaded image
🥳嵌入式 Linux开发
多核异构核间通信
Words 4212Read Time 11 min
2024-9-24
2024-12-12
type
date
slug
category
icon
password

一、介绍

随着信息技术的发展与需求的提升,传统单核 SoC 不能满足需求,促进了同构多核与异构多核的发展,在异构多核框架中,整个系统中由多个不同的处理器、性能与用途格不相同的多个核心组成,各个核心发挥各自的计算优势,实现资源的最佳配置,很好的提升了整体性能,降低功耗,简化开发模式,因此多核间的通信机制,以及软件编程模型对多核性能的发挥尤为重要。本文介绍异构核间通信机制,考虑的因素有:
  • 轻量级,可应用于 NOS / RTOS 的应用场景
  • 简化各核心的开发模式
  • 针对核间协同工作的特点,划分为:通用计算、并行计算、流式数据、帧式数据,应用于多种异构场景
  • 可移植性,框架可以方便移植到 Linux,不同的 RTOS 中
异构多核处理器大多采用主从式的结构。主从式结构根据不同核的功能把处理器核分为主核和从核。主核的结构和功能一般较为复杂,负责全局资源、任务的管理和调度并完成从核的引导加载。从核主要接受主核的管理,负责运行主核分配的任务,并具有本地任务调度与管理功能。在多核处理器中,根据不同核的结构,各个核可运行相同或不同的操作系统。
近几年各大芯片公司看到产品的发展趋势,均推出了一些单芯异构多核处理器,比较知名的为ST公司的STM32MP157 系列,NXP的i.MX8 系列,瑞萨的rzg2l系列。其原理基本一致,基于共享内存传输数据,基于寄存器和中断传递状态
Modern SoCs typically employ heterogeneous remote processor devices in asymmetric multiprocessing (AMP) configurations, which may be running different instances of operating system, whether it's Linux or any other flavor of real-time OS.
OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP. Typically, the dual cortex-A9 is running Linux in a SMP configuration, and each of the other three cores (two M3 cores and a DSP) is running its own instance of RTOS in an AMP configuration.
Typically AMP remote processors employ dedicated DSP codecs and multimedia hardware accelerators, and therefore are often used to offload CPU-intensive multimedia tasks from the main application processor.
These remote processors could also be used to control latency-sensitive sensors, drive random hardware blocks, or just perform background tasks while the main CPU is idling.
 

1.1 常用概念

Remoteproc:主处理器上的Linux操作系统可以对远程处理器及其相关软件环境进行生命周期管理,即启动或关闭远程处理器。
notion image
 
IPCC处理器间通信控制器:MHU(Message Handling Unit)是MPU芯片内的一个IP模块,担任IPCC角色,用于Cortex-A55(CA55)之间或与Cortex-M33(CM33)之间的消息通信。数据传输通过共享内存方式实现。
notion image

1.2 系统架构

 
notion image

1.2.1 传输层

RPMsg framework:是Linux系统基于Virtio缓存队列实现的主处理核和协处理核间进行消息通信的框架。
  • Linux RPMsg 框架
    • 基于virtio vring
    • 利用Linux Mailbox framework
    • Linux内核驱动源码位于(drivers/rpmsg)
    • Linux内核源码目录给出的rpmsg client的示例代码位置如下samples/rpmsg/rpmsg_client_sample.c
  • 远程处理器端 RPMSG 框架
    • ST 采用 OpenAMP 方案 Github OpenAMP框架 。
    • NXP 采用 RPMsg-Lite 方案
      • The RPMsg-Lite is an open-source component developed by NXP Semiconductors and released under the BSD-compatible license.
      • 优点:小内存占用,适合单片机,支持静态内存分配;
      • Component / Configuration
        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%
        notion image
        notion image
      notion image

1.2.2 MAC 层

  • Virtio是通用的IO虚拟化模型,位于设备之上的抽象层(通知机制、队列数据管理、分发不同驱动处理

1.2.3 硬件层

STM32MP157 - Mailbox framework
notion image
  • 一个邮箱控制器(mailbox controller),依赖于硬件平台实现,比如MP157的IPCC外设:
    • 它负责配置和处理来自IPCC外围设备的IRQ。
    • 它为邮箱客户端提供了通用API。
  • 一个邮箱客户端(mailbox client),负责发送或接收消息。
 
MX8MP - Messaging Unit
  • 物理内存DDR :划分为 TXVring Buffer 和 RXVring Buffer
  • 消息传递单元(MessagingUnit,简称MU):通信协调管理(寄存器中断方式)
    • notion image
 
RemoteProc framework
  • A7 核端:remoteproc
    • 将ELF固件加载到远程处理器内存中。
    • 解析固件资源表以设置关联的资源(例如IPC,内存分割和跟踪)。
    • 控制远程处理器的执行(启动,停止…)。
    • 提供监视和调试远程固件的服务。
  • M4 核端:stm32_rproc
    • 将stm32特定的功能(回调)注册到RPROC框架。
    • 处理与远程处理器关联的平台资源(例如寄存器,看门狗,复位,时钟和存储器)。
    • 通过邮箱框架将通知(通知)转发到远程处理器。
    • notion image
 

1.3 应用层架构

notion image

1.4 瑞萨开发环境

客户可以使用灵活的软件包(FSP)快速开发应用程序,使用OpenAMP创建与Linux配合使用的应用程序。
notion image
notion image

小节引用

二、共享内存 Shared Memory

notion image

三、虚拟设备框架 Virtio

Virtio是一个共享内存管理的虚拟设备框架,Virtio中的vring是指向数据缓冲区指针的FIFO队列,有两个单向的vring,一个vring专用于发送到远程处理器的消息,另一个vring用于从远程处理器接收的消息, 数据就存放于共享的内存中,即Vring buffers, 一半用于发送,一半用于接收。
Virtio is an open standard that defines a protocol for communication between drivers and devices of different types, see Chapter 5 ("Device Types") of the virtio spec ([1]). Originally developed as a standard for paravirtualized devices implemented by a hypervisor, it can be used to interface any compliant device (real or emulated) with a driver.
For illustrative purposes, this document will focus on the common case of a Linux kernel running in a virtual machine and using paravirtualized devices provided by the hypervisor, which exposes them as virtio devices via standard mechanisms such as PCI.

Buffers and notifications: The work routine

  • virtqueue 缓存队列,只读只写
  • 提供设备通知方法,包括数据添加到队列,
    • 底层驱动决定设计通知分发方法(PCI 终端或者写内存)
    • 异步通知,防止分布过载
  • Split virtqueue: the beauty of simplicity
    • Descriptor Area: used for describing buffers.
    • Driver Area: data supplied by driver to the device. Also called avail virtqueue.
    • Device Area: data supplied by device to driver. Also called used virtqueue.
  • Descriptor ring: Where is my data?
    • Avail ring: Supplying data to the device
      • notion image
    • Chained descriptors: Supplying large data to the device
      • notion image
    • Used virtqueue layout
      • notion image

    四、RPmsg

    Rpmsg 框架是一种基于Virtio的消息总线,支持内核驱动和远端处理器通讯,当写rpmsg驱动支持通讯,需要注意:
    1. 远端处理器有系统物理内存和其他硬件资源的访问权限。(e.g. on OMAP4, remote cores and hardware accelerators may have direct access to the physical memory, gpio banks, dma controllers, i2c bus, gptimers, mailbox devices, hwspinlocks, etc..)
    1. 限制特定 rpmsg 通道,防止用户代码利用bug导致系统失控

    rpmsg_send() 函数

    从给定端点向远程处理器发送消息
    参数
    描述
    ept
    给定端点给src
    data
    要发送的数据
    len
    字节长度
    返回值
    成功返回0 失败返回错误码
    注意:若TX 缓存不可得,函数会阻塞直到一个缓存可获得。(until the remote processor consumes a tx buffer and puts it back on virtio's used descriptor ring)

    rpmsg_sendto() 函数

     
    将消息从给定端点发送到远程处理器,发送到调用方提供的目标地址。
    参数
    描述
    ept
    给定端点给src
    data
    要发送的数据
    len
    字节长度
    dst
    an explicit destination address
    返回值
    成功返回0 失败返回错误码

    rpmsg_send_offchannel() 函数

    使用用户提供的SRC和DST地址向远程处理器发送消息。
    参数
    描述
    ept
    给定端点给src
    src
    an explicit source address
    dst
    an explicit destination address
    data
    要发送的数据
    len
    字节长度
    返回值
    成功返回0 失败返回错误码
    忽略endpoint 隶属的源和目标地址,使用用户提供的地址

    rpmsg_trysend() rpmsg_trysendto() rpmsg_trysend_offchannel() 函数

    注意:若没有多余的发送缓冲区,函数会立刻返回,不会阻塞超时推退出
    In case there are no TX buffers available, the function will immediately return -ENOMEM without waiting until one becomes available.
     

    rpmsg_create_ept()

    This function allows drivers to create such an endpoint, and by that, bind a callback, and possibly some private data too, to an rpmsg address (either one that is known in advance, or one that will be dynamically assigned for them).
    参数
    描述
    rpdev
    给定端点给src
    cb
    rx callback
    priv
    private data
    chinfo
    返回值
    Returns a pointer to the endpoint on success, or NULL on error.

    other api

     

    Typical Uauage

    小节引用

    1. RPMsg - Wikipedia
    1. Remote Processor Messaging (rpmsg) Framework — The Linux Kernel documentation
    1. Virtio on Linux — The Linux Kernel documentation

    五、IMX8MP使用双核通讯实例

    5.1 功能需求和框架

    功能模块
    子功能
    备注
    实时事件记录、查询
    1、事件发生通知机制 2、记录带发生时间戳(精确到ms?),共享内存传递数据需带时间戳 4、格式:接收到故障时间信息即时保存到 txt 5、名称:单天数据保存一个文件,并以当天时间命名 6、提供单条数据查询接口,实时认为查询时间和存储时间相隔10s内
    历史事件存储、查询
    提供多条数据查询接口(10 条) 1、APP发送查询命令,串口解析 2、M核发送,A核接收查询命令 3、txt 中查询最新十条数据 4、字符串数组通过rpmsg发送到M核 5、串口上发字符串数组
    配置文件(ini)保存和读写
    notion image

    5.2 接口设计

    5.2.1 BLDC 事件记录

    BLDC 事件记录时间戳和故障位信息,其中时间戳通过读取get_ds1302_time(timestamp_t *timestamp),故障位信息通过get_bldc_fault_bit(uint32_t *event_details)

    5.2.2 双核通讯说明

    F1 获取时间戳 + 时间戳
    发送包: F1+ [2022 10 20 19 43 54 ] + \r\n -> [F1 07 E6 0A 14 13 2B 36 0D 0A 00 00 00 00] 字节数 10bytes
    响应包: 日志记录条数-> [15]
    F2 创建记录 + 记录内容
    发送包 :F2 [2022 10 20 19 43 54 0x12345678]+\r\n -> [F2 07 E6 0A 14 13 2B 36 12 34 56 78 0D 0A ] 字节数 14 bytes
    响应包: 日志记录条数 -> [15]
    F3 查询接口 + 查询条数
    发送包: F3 10 + \r\n -> [F3 0A 0D 0A 00 00 00 00 00 00 00 00 00 00] 字节数 14 bytes
    响应包: 查询到若干条记录-> [F3 07 E6 0A 14 13 2B 36 12 34 56 78 0D 0A ] ... [F3 07 E6 0A 14 13 2B 36 12 34 56 78 0D 0A ] 字节数 10*14 =140 bytes
    F4 写参数+ 区,键,值 (section,key,value)
    发送包: F4,protectValue,overVoltage,100, \r\n -> [F4 2c 70 72 6f 74 65 63 74 56 61 6c 75 65 2c 6f 76 65 72 56 6f 6c 74 61 67 65 2c 31 30 30 2c 0D 0A] 字节数:100,不足补 00
    响应包: 成功标志 0xAA
    F5 读取配置参数
    发送包: F5,protectValue,overVoltage,\r\n -> [F5 2c 70 72 6f 74 65 63 74 56 61 6c 75 65 2c 6f 76 65 72 56 6f 6c 74 61 67 65 2c 0D 0A] 字节数:100,不足补 00
    响应包: 参数值转化为字符串发送过去 31 30 30 0D 0A 返回长度不一致

    5.3 程序设计流程图

    5.3.1 单进程工作流程

    notion image

    5.3.2 多进程工作流程

    notion image
     
     

    5.4 移植 FreeRTOS和RPMSG

    FreeRTOS和RPMSG移植

    5.5 修正引脚复用冲突

    5.5.1 确定引脚复用设置

    使用 MCUXpressor_config_tools 查看A核引脚复用设置
    notion image
    如下:

    5.5.2 更改设备树设置

    1. 进入虚拟机,进入路径,打开设备树文件
      1. 由【pinctrl_i2c3】搜索到 【&i2c3】分组,注释掉工作状态status Line 602 "okay" -> "disabled",即关闭掉设备树中设置i2c3z中引脚设置。
          • Line 602 "okay" -> "disabled"
      1. 对于A核和M核引脚复用情况一致的,保留A核
          • Line 1006 "okay" -> "okay"
          • Line 1330/1331 0x140 -> 0x146
      注意:对于uart3串口复用冲突,更改 OK8MP-C-bak.dts 文件和 imx8mp.dtsi
      OK8MP-C-bak.dts
      imx8mp.dtsi

      5.5.3 编译 dtb 和 image 镜像

      完成上述修改后保存设备树,返回命令行进行编译

      5.5.4 替换dtb和image镜像

      替换文件:将 kernel 下 OK8MP-C.dtb 和 Image 文件拷贝到 /run/media/mmcblk2p1文件下,并reboot启动测试
      notion image

      5.6 源代码分析

       

      引用

      1. AUTOSAR架构下多核通信 (qq.com)
      1. 【韦东山】2020-08-19 直播公开课录像回放_多核异构下不同操作系统之间的协同_哔哩哔哩_bilibili
       
      上一篇
      多线程、并发与线程同步
      下一篇
      嵌入式硬件基础

      Comments
      Loading...