RPMsg:协议简介

2023-05-16

RPMsg:协议简介

本篇文章转载于简书,在此做个整理和备份,方便查阅 在此感谢原博主SunnyZhou1024

  • RPMsg:协议简介
    • 0. 起因
    • 1. AMP
    • 2. RPMsg
      • 2.1. Linux中的RPMsg
      • 2.2. 原理
      • 2.3. 协议
    • 3. API
    • 4.4. References

0. 起因

之前在RPC原理与FastRPC实现一文中介绍过RPC的原理,简而言之,RPC就是实现本地程序调用位于另一个地址空间的例程(routine)的一种技术手段,其基本架构如图0-1所示。
图0-1 RPC基本架构

图0-1 RPC基本架构

由于RPC只是一种技术手段,并没有一个统一的标准,因此,每一种RPC框架根据其应用场景不同,所采用的实现方式也不尽相同。这些差异主要集中在两个方面:

  1. 数据的序列化和反序列化方法不同:例如可以使用JSON、XML以及谷歌推出的Protocol Buffer、Flat Buffer等格式作为数据传递格式,甚至是自己定义的一套格式;
  2. 数据传递方法不一样:例如可以通过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-1 Linux中RPMsg代码结构

图2-1 Linux中RPMsg代码结构

2.2. 原理

在AMP系统中,主-从核心通过共享内存的方式进行通信,如图2-2所示。内存的管理由主核负责,在每个通信方向上都有两个缓冲区,分别是USED和AVAIL,这个缓冲区可以按照RPMsg中消息的格式分成一块一块链接形成一个环,如图2-3所示。
图2-2 AMP中主从通信方式

图2-2 AMP中主从通信方式

在这里插入图片描述

图2-3 RPMsg中的消息缓冲区示意图

当主核需要和从核进行通信的时候可以分为四步,如图2-4所示:

  1. 主核先从USED中取得一块内存;
  2. 将消息按照消息协议填充;
  3. 将该内存链接到AVAIL换中;
  4. 触发中断,通知从核有消息处理。
    图2-4 主核发消息给从核
    图2-4 主核发消息给从核

反过来,从核需要和主核通信的时候也类似,如图2-5所示:

  1. 主核先从AVAIL中取得一块内存;
  2. 将消息按照消息协议填充;
  3. 将该内存链接到USED换中;
  4. 触发中断,通知主核有消息处理。
    图2-5 从核发消息给主核
    图2-5 从核发消息给主核

2.3. 协议

既然是一种信息交换的协议,与TCP/IP类似,RPMsg协议也有分层,主要分为三层,分别是传输层、MAC层和物理层,如图2-6所示:

在这里插入图片描述

图2-6 RPMsg协议层

各层在Linux代码的对应情况如图2-7所示。
图2-7 RPMsg结构

图2-7 RPMsg结构

并且,在rpmsg 总线上的消息都具有以下结构,包含消息头和数据两部分。消息头与TCP/IP协议的UDP包非常像,并且是固定的,如图2-8所示。

图2-8 RPMsg消息格式

图2-8 RPMsg消息格式

该消息格式的定义位于drivers/rpmsg/virtio_rpmsg_bus.c中,具体定义如下。

struct rpmsg_hdr {
    u32 src;
    u32 dst;
    u32 reserved;
    u16 len;
    u16 flags;
    u8 data[];
} __packed;

3. API

虽然目前RPMsg并未形成相关的标准文档,但Linux内核中已经有了RPMsg的实现并给出了相关定义,OpenAMP也参照Linux中的定义做出了自己的实现。因此,这里对相关的API做些简单的介绍。可能在不久的将来,RPMsg可以从一个事实上的标准变成一个真正的标准,毕竟,TCP/IP 也是这么过来的嘛。

  1. RPMsg virtio主核初始化共享缓冲池(RPMsg virtio 从核不需要用到这个API):
void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool,
              void *shbuf, size_t size)
  1. 初始化RPMsg virtio 设备:
int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
          struct virtio_device *vdev,
          rpmsg_ns_bind_cb ns_bind_cb,
          struct metal_io_region *shm_io,
          struct rpmsg_virtio_shm_pool *shpool)
  1. 销毁 RPMsg virtio 设备:
void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev)
  1. 从RPMsg virtio设备中获取RPMsg设备:
struct rpmsg_device *rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev)
  1. 创建 RPMsg 终端:
int rpmsg_create_ept(struct rpmsg_endpoint *ept,
           struct rpmsg_device *rdev,
           const char *name, uint32_t src, uint32_t dest,
           rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb)
  1. 销毁 RPMsg 终端:
void rpmsg_destroy_ept(struct rpsmg_endpoint *ept)
  1. 检查本地RPMsg 终端是否已经与远程的终端绑定,以及是够已经准备好可以发送信息:
int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
  1. 通过默认的RPMsg 终端发送信息:
int rpmsg_send(struct rpmsg_endpoint *ept, const void *data, int len)
  1. 通过制定的终端以以及目的地地址发送信息:
int rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len,
       uint32_t dst)
  1. 通过指定原地址和目的地址发送消息:
int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
            uint32_t src, uint32_t dst,
            const void *data, int len)
  1. 尝试通过默认的终端发送信息,如果当前没有缓存可用则返回:
int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
        int len)
  1. 尝试通过制定的终端以以及目的地地址发送信息,如果当前没有缓存可用则返回:
int rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len,
          uint32_t dst)
  1. 尝试通过指定原地址和目的地址发送消息,如果当前没有缓存可用则返回:
int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
               uint32_t src, uint32_t dst,
               const void *data, int len)

4.4. References

[1] Asymmetric Multiprocessing and Embedded Linux
[2] AMP Intro
[3] rpmsg-lite
[4] rpmsg

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RPMsg:协议简介 的相关文章

  • 编程——两种list的翻转方法

    对于题目相信大家都比较熟悉了 xff0c 下面就直接上代码了 xff0c 其中没有给出list的creat函数 xff0c 有兴趣的同学可以自己实现 1 模板node的定义 template lt class T gt class TNod
  • 数组旋转新方法

    题目 xff1a 对一个int数组进行左右任意长度的旋转 xff0c 如 xff1a 原始数组为 1 2 3 4 5 xff0c 左旋两位 xff08 可用 2表示 xff09 得 3 4 5 1 2 xff0c 右旋两位 xff08 可用
  • 为什么链表操作过程中对于结构体指针,都要用malloc来开辟内存空间

    sqlist h ifndef SQLIST H define SQLIST H include lt stdio h gt include lt stdlib h gt define maxsize 1024 线性表的最大长度 typed
  • P1706 全排列问题

    原题 P1706 全排列问题 这题显然可以暴力 长达164行 include lt iostream gt include lt istream gt include lt ostream gt include lt cstdio gt i
  • 自动化专业考研方向简介

    自动化专业考研方向简介 xff08 一 xff09 大家在准备考研时 xff0c 想没想过 自己对什么感兴趣 xff1f 自己以后想干什么 xff1f 毕业后如何打算 xff1f 如果你认真考虑了这几个问题 xff0c 相信你的未来研究生生
  • UVA1185 Big Number

    原题 https www luogu com cn problem UVA1185 本题用到的定理的证明 https www cnblogs com weiliuyby p 5831991 html 题目 给出n 求n 的位数 从网上找到了
  • 浅谈威佐夫博弈

    如果不了解威佐夫博弈的话 xff0c 下面有威佐夫博弈的介绍 有两堆石子 xff0c 数量任意 xff0c 可以不同 游戏开始由两个人轮流取石子 游戏规定 xff0c 每次有两种不同的取法 xff0c 一是可以在任意的一堆中取走任意多的石子
  • YBT1325:循环比赛日程表

    我们先看题 我们仔细观察就会发现一下规律 xff1a 设一个数 设两个数 且 1 在的范围内 有 2 在的范围内 有 3 在的范围内 有 以上三条我都验证过了 正确 所以代码就出来了 include lt iostream gt using
  • Codeforces Contest #1553 A : Digit Sum 题解

    题目链接 Digit Sum 题面 将上面一大坨翻译一下 xff0c 就是 xff1a 定义函数的数字和 给出 求有多少个满足且 若模余 xff0c 则成立 一开始想是输出的下取整 xff0c 最后的结果 xff1a 没有考虑到的情况 xf
  • Atcoder Beginner Contest 100 - 题解

    A 原题 Happy Birthday 本题其实很水 只需要输入这两个整数 xff0c 如果中有一个大于 就输出 xff0c 否则输出 Yay include lt bits stdc 43 43 h gt using namespace
  • ubuntu 18.04 server 扩容(LVM)磁盘 解决磁盘不足的情况 (亲测)

    因为发现我的本地server出现磁盘满了的情况 所以进行lvm的扩容 截图的都是扩容后的 所以忽略容量 1 查看磁盘情况 df span class hljs attribute h span 原本发现 dev mapper ubuntu
  • 欢迎使用CSDN-markdown编辑器

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • 工作一年,辞职复习半年,考杭电计算机的经验分享

    工作一年 xff0c 辞职复习半年 xff0c 考杭电计算机的经验分享 如果 xff0c 毕业了工作顺利的人大概率是不会去考研的 xff0c 去考研的人 xff0c 大概率是想改变的 题记 2019 4 6 关于我 纠结的人生 为什么考研
  • CSS表格样式

    文章目录 CSS表格样式caption side 标题位置border collapse 边框合并border spacing 边框间距css样式 xff08 推荐使用 xff09 CSS表格样式 caption side 标题位置 语法
  • Android使用Annotations注解优化代码

    文章目录 Android使用Annotations注解优化代码Null 注解Typedef 注解Resource Type 注解Threading 注解Value Constraints 注解Overriding Methods 注解Ret
  • C语言strstr函数

    函数strstr定义 xff1a char strstr const char str1 const char str2 xff1b 位于头文件 string h 中 作用 xff1a strstr函数用于判断字符串str2是否为字符串st
  • Linux下串口读写通信

    span class token keyword int span fd span class token operator 61 span span class token number 0 span span class token p
  • kubernetes最新版安装单机版v1.21.5

    kubernetes最新版安装单机版v1 21 5 k8s集群由Master节点和Node xff08 Worker xff09 节点组成 今天我在这里给大家只用1台机器 xff0c 安装kubernetes 1 安装前置环境 root 6
  • 双系统、多系统快速切换

    前言 装双系统甚至多系统 xff0c 是为了满足不同需求 每个操作系统都有自身的特点 xff0c 因为这样那样的原因 xff0c 很多人选择双系统 双系统满足了不同需求 xff0c 但是每次需要手动选择所要进入的系统 xff0c 切换系统也
  • ROS::CmakeList 例子

    ROS CmakeList 例子 span class token function cmake minimum required span span class token punctuation span VERSION span cl

随机推荐

  • ROS:静态TF发布

    ROS xff1a 静态TF发布 方式1 xff1a span class token tag span class token tag span class token punctuation lt span launch span sp
  • ROS::线程锁

    ROS xff1a xff1a 线程锁 boost span class token operator span mutex mutex span class token punctuation span span class token
  • 无人机智能飞行类库设计构思

    搭建无人机 智能飞行类库的主要目的就在于 xff1a 便于无人机路径规划各种算法的实施 xff0c 便于飞行仿真以及便于今后在硬件上实现算法 完整做到这些需要做三方面做工作 xff1a 一 计算几何 计算几何问题主要用于路径优化 避障等 x
  • STL教程:C++ STL快速入门

    目录 1 STL引言 2 STL是什么 xff08 STL简介 xff09 3 STL历史 4 STL组件 5 STL基本结构 6 STL 使用方法 7 STL目录 网址 xff1a STL教程 xff1a C 43 43 STL快速入门
  • vue使用sortablejs插件的时候报Sortable: `el` must be an HTMLElement

    最近因为项目需要很灵活自定义查询 xff0c 故使用了vue和element ui组件库 xff0c 其中el table需要行和列拖拽排序 故使用到了sortable插件 一 报错的排查 首先对 xff1a const tbody 61
  • 记一次Linux 4.15.0-65-generic安装Elasticsearch成功的过程

    一 xff0c 操作系统和安装的应用 xff1a 1 操作系统 xff1a Linux version 4 15 0 65 generic buildd 64 lgw01 amd64 006 gcc version 7 4 0 Ubuntu
  • [docker]笔记-镜像 管理

    1 镜像管理 docker search xxxx 查找镜像 例如查找httpd root 64 localhost docker search httpd 下载镜像 docker pull xxxx root 64 localhost d
  • quill-editor扩展的正确姿势

    一 无关的插曲 曾几何时 xff0c 风云万里 xff0c 万海桑田 耕耘于代码堆里多年 做过android移动端 xff0c 做过web端 xff0c 做过java后端和 net xff0c 也做过python数据分析 但真正扩展源码的亦
  • 导入excel时js转换时间的正确姿势

    一 基础 1 excel的日期是以1900 1 0开始计算的 xff0c 既1900 1 1就是1天 xff1b 2 js的Date是以 1970 1 1 08 00 00 开始的 xff1b excel时间换算如下 xff1a 点击常规后
  • springboot下ClassUtils.getDefaultClassLoader().getResource(“static“).getPath() 空指针异常???

    在static加个文件文件就ok xff0c 不信你看看
  • Compilation failure: Compilation failure

    有a项目和b项目 xff0c 如果a项目打包成功 xff0c b依赖a 现b打包的时候报Compilation failure Compilation failure了 xff0c 原因是a中有 span class token opera
  • mysql数据更新时变更时间自动更新

    ALTER TABLE test CHANGE startTime startTime timestamp NOT NULL ON UPDATE CURRENT TIMESTAMP DEFAULT CURRENT TIMESTAMP
  • docker、docker-compose和Portainer的安装

    一 docker安装 span class token comment 安装docker相关依赖 span yum span class token function install span y yum utils device mapp
  • vue-cli+spring boot前后端分离跨域及session丢失解决办法

    前后端分离跨域笔记 小小的唠叨前端代码后端 小小的唠叨 曾几何时 xff0c 项目开发时间很紧 xff0c 项目组很多的人即不懂vue也不大懂spring boot及mybatic的强大之处 xff0c 也没有做过前后端分离 xff0c 项
  • vue打包整合到spring boot一记

    目录 背景vue cli打包之前的配置总结 背景 前段时间 xff0c 根据需求 xff0c 要将项目烧入到芯片 xff0c 但我的擅长之处就是前后端分离开发 xff0c 因此需要前端vue开发好 xff0c 打包放到后端里面一起执行 那时
  • 小四轴编程入门教程

    小四轴编程入门教程之一 xff1a 陀螺仪和加速度计 在小四轴中 xff0c 陀螺仪是一种用于测量小四轴旋转速度的传感器 xff0c 它测量的是角速度 xff0c 是指物体在单位时间内转过的角度大小 通过测量物体在X Y Z三个轴上的角速度
  • 从0开始教你三天完成毕业设计-后端api

    目录 前言 开始 env 数据库配置文件 app controller 控制器接口api 工具类 分类表 categoryController 收藏表 collecetionController 商品表 goodController 订单表
  • ZYNQ双核通信 Linux+FreeRTOS(一)

    ZYNQ 双核通信 一 OpenAMP开发换环境搭建编译U boot编译Kernel编译设备树什么是devicetree xff1f Devicetree基础设备树属性设备树生成器 xff08 DTG xff09 Task Output P
  • ZYNQ 安装ubuntu文件系统

    ZYNQ 7020 Ubuntu16 04文件系统安装 在关于zynq openamp的章节我们已经完成了zynq 的u boot 内核 xff0c 设备树的制作 xff0c 通过XSDK完成了启动文件的创建 同样道理制作zynq7020的
  • RPMsg:协议简介

    RPMsg xff1a 协议简介 本篇文章转载于简书 xff0c 在此做个整理和备份 xff0c 方便查阅 在此感谢原博主SunnyZhou1024 RPMsg xff1a 协议简介0 起因1 AMP2 RPMsg2 1 Linux中的RP