RPMsg-Lite上手
文章目录
- 1、rpmsg-lite介绍
- 2、rpmsg-lite 应用
现在的芯片非常复杂,很多都是包含多个核,特别是片上系统(SoC),一颗芯片上不仅包含了很多个核心,并且很多核心都是异构的。
为了最大限度的发挥他们的性能,协同完成某一任务,不同的核心上面运行的系统可能各不相同,有些核心上面运行的通用系统例如 Linux、Android 等,另外一些核心上可能运行的就是实时操作系统(RTOS)等。这些不同架构的核心以及他们上面所运行的软件组合在一起,就成了异构多处理系统(Asymmetric Multiprocessing System)。

异构多处理系统中往往会形成主-从(Master-Slave)结构。主核上的系统先启动,并负责准备好运行环境,然后根据需要或者一定规则启动从核并对其进行管理。主-从核心上的系统都准备好之后,他们之间就通过 IPC(Inter Processor Communication)方式进行通信,而 RPMsg 就是 IPC 中的一种。
RPMsg,全称 Remote Processor Messaging,它定义了异构多核处理系统(AMP,Asymmetric Multiprocessing)中核与核之间进行通信时所使用的标准二进制接口。
对于非通用的操作系统,它上面很可能是没有搭载传统的 TCP/IP 协议栈的,因此,当主核想要通过 RPC 的方式调用从核上的服务的时候,便不能使用一般的 RPC 框架所采用的网络通信方式。这时候类似于 RPMsg 这种专门用于核间通信的通信协议就派上了用场。

1、rpmsg-lite介绍
RPMsg-Lite 是远程处理器消息传递(RPMsg)协议的轻量级实现。 RPMsg 协议定义了标准化的二进制接口,该接口用于在异构多核系统中的多个核之间进行通信。与开放式非对称多处理(OpenAMP)框架的 RPMsg 实现相比,RPMsg-Lite 减少了代码大小,简化了 API,并提高了模块性。
RPMsg-Lite 是由 NXP Semiconductors 开发并在 BSD 兼容许可下发布的开源组件。
官方仓库为:https://github.com/nxp-mcuxpresso/rpmsg-lite
官方详细使用的指南:https://nxp-mcuxpresso.github.io/rpmsg-lite
下载 rpmsg-lite 源码后,查看源码文件较少
$ tree -L 2
.
├── common
│ └── llist.c
├── include
│ ├── environment
│ ├── llist.h
│ ├── platform
│ ├── 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
│ ├── rpmsg_lite.c
│ ├── rpmsg_ns.c
│ └── rpmsg_queue.c
└── virtio└── virtqueue.c
RPMsg-Lite 的实现可以分为三个子组件,核心组件位于 rpmsg_lite.c 中,rpmsg_ns.c 和 rpmsg_queue.c 是可选的组件。两个可选组件用于实现阻塞接收 API(在 rpmsg_queue.c 中)和动态“命名”端点创建和删除公告服务(在 rpmsg_ns.c 中)。
媒体访问层 是在 virtqueue.c 中实现的,它是与 OpenAMP 实现共享的少数几个文件之一。该层主要定义了共享内存模型,内部定义了使用的组件,如vring或virtqueue。

2、rpmsg-lite 应用
nxp 有很多 AMP 的芯片(如:frdmk32l3a6、imxrt1160、imxrt1170、lpcxpresso55s69、lpcxpresso54114等),都是基于 rpmsg-lite 的实现的核间通信,可下载对应SDK https://github.com/nxp-mcuxpresso/mcux-sdk-examples 学习。
下面通过 lpcxpresso54114 中的示例展示 rpmsg 中比较典型的 pingpong 应用实现。

lpcxpresso54114 中 master 端是 Cortex-M4 核, remote 端 Cortex-M0 + 核。
- master 端
static void app_nameservice_isr_cb(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data)
{uint32_t *data = (uint32_t *)user_data;*data = new_ept;
}void app_task_master(void *param)
{volatile uint32_t remote_addr = 0U;struct rpmsg_lite_endpoint *my_ept;rpmsg_queue_handle my_queue;struct rpmsg_lite_instance *my_rpmsg;rpmsg_ns_handle ns_handle;my_rpmsg =rpmsg_lite_master_init((void *)RPMSG_LITE_SHMEM_BASE, SH_MEM_TOTAL_SIZE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);my_queue = rpmsg_queue_create(my_rpmsg);my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, rpmsg_queue_rx_cb, my_queue);ns_handle = rpmsg_ns_bind(my_rpmsg, app_nameservice_isr_cb, (void *)&remote_addr);/* Wait until the secondary core application issues the nameservice isr and the remote endpoint address is known. */while (0U == remote_addr){};/* Send the first message to the remoteproc */msg.DATA = 0U;(void)rpmsg_lite_send(my_rpmsg, my_ept, remote_addr, (char *)&msg, sizeof(THE_MESSAGE), RL_DONT_BLOCK);while (msg.DATA <= 100U){(void)rpmsg_queue_recv(my_rpmsg, my_queue, (uint32_t *)&remote_addr, (char *)&msg, sizeof(THE_MESSAGE), &len,RL_BLOCK);(void)PRINTF("Primary core received a msg\r\n");(void)PRINTF("Message: Size=%x, DATA = %i\r\n", len, msg.DATA);msg.DATA++;(void)rpmsg_lite_send(my_rpmsg, my_ept, remote_addr, (char *)&msg, sizeof(THE_MESSAGE), RL_BLOCK);}(void)rpmsg_lite_destroy_ept(my_rpmsg, my_ept);my_ept = ((void *)0);(void)rpmsg_queue_destroy(my_rpmsg, my_queue);my_queue = ((void *)0);(void)rpmsg_ns_unbind(my_rpmsg, ns_handle);(void)rpmsg_lite_deinit(my_rpmsg);wile (1){vTaskDelay(1000);}
}
- remote 端
static void app_nameservice_isr_cb(uint32_t new_ept, const char *new_ept_name, uint32_t flags, void *user_data)
{
}void app_task_remote(void *param)
{volatile uint32_t remote_addr;volatile rpmsg_ns_handle ns_handle;my_rpmsg = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);rpmsg_lite_wait_for_link_up(my_rpmsg);(void)PRINTF("Link is up!\r\n");my_queue = rpmsg_queue_create(my_rpmsg);my_ept = rpmsg_lite_create_ept(my_rpmsg, LOCAL_EPT_ADDR, rpmsg_queue_rx_cb, my_queue);ns_handle = rpmsg_ns_bind(my_rpmsg, app_nameservice_isr_cb, ((void *)0));/* Introduce some delay to avoid NS announce message not being captured by the master side.This could happen when the remote side execution is too fast and the NS announce message is triggeredbefore the nameservice_isr_cb is registered on the master side. */SDK_DelayAtLeastUs(1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);(void)rpmsg_ns_announce(my_rpmsg, my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, (uint32_t)RL_NS_CREATE);(void)PRINTF("Nameservice announce sent.\r\n");while (msg.DATA <= 100U){(void)PRINTF("Waiting for ping...\r\n");(void)rpmsg_queue_recv(my_rpmsg, my_queue, (uint32_t *)&remote_addr, (char *)&msg, sizeof(THE_MESSAGE),((void *)0), RL_BLOCK);msg.DATA++;(void)PRINTF("Sending pong...\r\n");(void)rpmsg_lite_send(my_rpmsg, my_ept, remote_addr, (char *)&msg, sizeof(THE_MESSAGE), RL_BLOCK);}(void)PRINTF("Ping pong done, deinitializing...\r\n");(void)rpmsg_lite_destroy_ept(my_rpmsg, my_ept);my_ept = ((void *)0);(void)rpmsg_queue_destroy(my_rpmsg, my_queue);my_queue = ((void *)0);(void)rpmsg_ns_unbind(my_rpmsg, ns_handle);(void)rpmsg_lite_deinit(my_rpmsg);my_rpmsg = ((void *)0);msg.DATA = 0U;while (1){vTaskDelay(1000);}
}
相关文章:
RPMsg-Lite上手
文章目录 1、rpmsg-lite介绍2、rpmsg-lite 应用 现在的芯片非常复杂,很多都是包含多个核,特别是片上系统(SoC),一颗芯片上不仅包含了很多个核心,并且很多核心都是异构的。 为了最大限度的发挥他们的性能&am…...
基于YOLOv8 的 多边形区域内目标检测,跟踪,计数
文章大纲 使用OpenCV 进行多边形 角点获取yolov5 的样例实现基于 roboflow 开源库的实现roboflow 开源库 介绍基于YOLOv8 track 的 Polygon Zone 计数参考文献与学习路径自己实现使用 开源库使用OpenCV 进行多边形 角点获取 import cv2 def SetPoints(windowname, img):"…...
STSP中用于记录节点和旅行回路的四种数据结构
STSP中用于记录节点和旅行回路的四种数据结构 双链表结构2-level tree卫星结构k-level卫星结构树参考文献 对于TSP是是历史悠久的研究问题,直至现在已经有了很多成熟高效的算法来求解问题。在拥有好的求解算法的同时,优秀的数据结构可以同时大幅提升问题…...
【Spring】AOP切点表达式
文章目录 1、语法2、通配符3、execution4、within5、annotation6、args7、args8、bean9、this10、target11、target12、within13、表达式组合14、补充 1、语法 动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名) 举例: execution(public User c…...
设计模式再探——代理模式
目录 一、背景介绍二、思路&方案三、过程1.代理模式简介2.代理模式的类图3.代理模式代码4.代理模式还可以优化的地方5.代理模式的项目实战,优化后(只加了泛型方式,使用CGLIB的代理) 四、总结五、升华 一、背景介绍 最近在做产品过程中对于日志的统一…...
MySQL日志——查询日志
1.查询日志 show variables like %general%;修改mysql的配置文件 /etc/my.cnf文件,添加如下内容: #该选项用来开启查询日志,可选值:0或者1;0代表关闭,1代表开启 general_log1 #设置日志的文件名࿰…...
Java版本工程行业管理系统源码-专业的工程管理软件-提供一站式服务 em
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...
pytorch的CrossEntropyLoss交叉熵损失函数默认是平均值
pytorch中使用nn.CrossEntropyLoss()创建出来的交叉熵损失函数计算损失默认是求平均值的,即多个样本输入后获取的是一个均值标量,而不是样本大小的向量。 net nn.Linear(4, 2) loss nn.CrossEntropyLoss() X torch.rand(10, 4) y torch.ones(10, dt…...
【力扣】206. 反转链表 <链表指针>
【力扣】206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2 输入:head [1,2] 输出:[2,1] 示例 3 输入:…...
Java包装类(自动拆装箱)
包装类 为什么要有包装类? 在面向对象中,“一切皆为对象”,但是基本数据类型不符合这一理念,为了让基本类型也称为对象 便于类型之间的转化,数据类型之间的基本操作 转换方式: int ——> Integer ne…...
使用Golang反射技术实现一套有默认值的配置解析库
在实际开发中,我们往往会给一个逻辑设计一套配置文件,用于根据不同环境加载不同配置。 比如生产环境和测试环境数据库的地址不一样,我们就需要在配置文件中设置不同的值。但是配置文件中又有一些相同值的配置项,比如数据库的名称等…...
数据安全能力框架模型-详细解读(二)
数据安全能力框架构成 1) 数据安全治理 管理视角:从组织制度流程上提出要求,由于数据在各业务系统之间流转,需要设立高级管理层参与决策的数据安全管理部门,统筹和规划多部门之间的工作;需要设立跨组织的…...
【BASH】回顾与知识点梳理(八)
【BASH】回顾与知识点梳理 八 八. 正则表达式(正规表示法)8.1 什么是正规表示法8.2 基础正规表示法语系对正规表示法的影响grep 的一些进阶选项基础正规表示法练习例题一、搜寻特定字符串例题二、利用中括号 [] 来搜寻集合字符例题三、行首与行尾字符 ^ …...
rust报错“Utf8Error { valid_up_to: 1, error_len: Some(1) } }”
这个错误通常表示在尝试将字节序列解码为UTF-8字符时出现问题。它指出在索引1处发现了无效的字节序列,并且错误的长度为1个字节。 要解决这个问题,你可以尝试以下几种方法: 检查你的输入数据是否包含无效的字节序列。你可以使用一些调试工具…...
【Linux】节点之间配置免密登录
文章目录 1、实现2、原理3、SSH的理解 1、实现 先写实现,解决问题后有兴趣的自己看后面的原理。 以实现节点A(主)免密登录到节点B(从)为例:(注意例子里节点B被登录) 步骤一…...
【13】STM32·HAL库-正点原子SYSTEM文件夹 | SysTick工作原理、寄存器介绍 | printf函数使用、重定向
目录 1.sys文件夹介绍(掌握)2.deley文件夹介绍(掌握)2.1deley文件夹函数简介2.2SysTick工作原理2.3SysTick寄存器介绍2.4delay_init()函数(F1)2.5delay_us()函数(F1)2.6delay_ms()函…...
ansible配置文件案例
案例一 控制主机上的普通用户控制受控主机 控制端1台,受控端两台 1.将两台受控主机添加到/etc/hosts文件中 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhos…...
【大数据】Flink 从入门到实践(一):初步介绍
Flink 从入门到实践(一):初步介绍 Apache Flink 是一个框架和分布式处理引擎,用于在 无边界 和 有边界 数据流上进行 有状态 的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。 1.架构 1…...
大数据课程F4——HIve的其他操作
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握HIve的join; ⚪ 掌握HIve的查询和排序 ⚪ 掌握HIve的beeline ⚪ 掌握HIve的文件格式 ⚪ 掌握HIve的基本架构 ⚪ 掌握HIve的优化; 一、jo…...
React Native详解和代码实例
目录 一、React Native 的主要特点二、React Native 的工作原理三、React Native 的优缺点四、React Native 代码示例 React Native 是一个用于构建原生移动应用程序的 JavaScript 框架。它使用 React 库,允许开发者使用 JavaScript 编写应用程序的 UI 和逻辑&#…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
