35 Star 4 Fork 12

kenneth / 项目交付归档

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
LiteOS-A核间通信规格说明.md 18.17 KB
一键复制 编辑 原始数据 按行查看 历史
xiezuguo 提交于 2022-12-29 13:56 . 核间通信规格说明修正

1 核间通信

1.1 接口说明

1.1.1 rpmsg接口

1.1.1.1 rpmsg_send

int rpmsg_send(struct rpmsgg_endpoint *ept, const void *data, int len);

向远程处理器发送消息。基于ept发送长度为len的消息data。消息将使用ept的源地址和目标地址发送到信道所属的远程处理器。 如果没有可用的TX缓冲区,该功能将被阻止,直到一个缓冲区可用或超时15秒。

参数
  • ept :指向RPMsg终端的指针
  • data:待传输的数据
  • len : 待传输的数据大小
返回值
  • 成功,返回已发送的字节数
  • 失败,返回RPMSG_ERR_PARAM

错误码说明:

  • RPMSG_ERR_PARAM,ept是空指针。
备注

1.1.1.2 rpmsg_sendto

static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst);

向远程处理器发送消息到指定目的地dst。将长度为len的data发送到远程dst地址。消息将使用ept的源地址发送到ept通道 所属的远程处理器。如果没有可用的TX缓冲区,该功能将被阻止,直到一个缓冲区可用或超时15秒。

参数
  • ept :指向RPMsg终端的指针
  • data:待传输的数据
  • len : 待传输的数据大小
  • dst :信道的目的地地址
返回值
  • 成功,返回已发送的字节数
  • 失败,返回RPMSG_ERR_PARAM

错误码说明:

  • RPMSG_ERR_PARAM,ept是空指针。
备注

1.1.1.3 rpmsg_send_offchannel_raw

static inline int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src, uint32_t dst
                                            , const void *data, int len);

向远程处理器发送消息,指定源地址和目标地址。将长度为len的消息data从源@src地址发送到远程@dst地址, 消息将发送到通道所属的远程处理器。消息将发送到通道所属的远程处理器。

参数
  • ept :指向RPMsg终端的指针
  • src :信道源地址
  • dst :信道的目的地地址
  • data:待传输的数据
  • len : 待传输的数据大小
  • wait:判断是否需要等待缓冲区为可用
返回值
  • 成功,返回发送数据的大小
  • 失败,返回RPMSG_ERR_PARAM

错误码说明:

  • RPMSG_ERR_PARAM,pathname是空指针。
备注

1.1.1.4 rpmsg_trysend

static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data, int len);

在@ept通道上发送长度为len的消息data。消息将使用ept的源地址和目标地址发送到ept通道所属的远程处理器。 如果没有可用的TX缓冲区,该函数将立即返回错误码,而无需等待一个可用的缓冲区

参数
  • ept :指向RPMsg 终端的指针
  • data:待传输的数据
  • len : 待传输的数据大小
返回值
  • 成功,返回发送数据的大小
  • 失败,返回RPMSG_ERR_PARAM

错误码说明:

  • RPMSG_ERR_PARAM,ept是空指针。
备注

1.1.1.5 rpmsg_trysendto

static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data, int len, uint32_t dst);

将长度为len的data发送到远程@dst地址。消息将使用ept的源地址发送到ept通道所属的远程处理器。如果没有可用的 TX缓冲区,函数将立即返回错误码-ENOMM,而无需等待一个可用缓冲器。

参数
  • ept :指向RPMsg终端的指针
  • data:待传输的数据
  • len : 待传输的数据大小
  • dst :信道的目的地地址
返回值
  • 成功,返回发送数据的大小
  • 失败,返回RPMSG_ERR_PARAM

错误码说明:

  • RPMSG_ERR_PARAM,ept是空指针。
备注

1.1.1.6 is_rpmsg_ept_ready

static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept);

检查本地RPMsg 终端是否已经与远程的终端绑定,以及是够已经准备好可以发送信息

参数
  • ept:指向RPMsg终端的指针
返回值
  • 成功,如果rpmsg端点同时设置了本地地址和目标地址,则返回1
  • 失败,返回0
备注

1.1.1.7 rpmsg_create_ept

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);

创建rpmsg端点并将其注册到rpmsg设备,创建rpmsg端点,使用名称、源地址、远程进程地址、端点回调和销毁端点 回调对其进行初始化,然后将其注册至rpmsg设备。本质上,rpmsg端点表示rpmsg总线上的侦听器,因为它将rpmsg地 址与rx回调处理程序绑定。Rpmsg客户端应该创建一个端点与远程关联。rpmsg客户端至少提供一个通道名称、消息通 知的回调,默认情况下,端点源地址应设置为rpmsg_ADDR_ANY。一些rpmsg客户端可以指定具有特定源地址的端点

参数
  • ept :指向RPMsg终端的指针
  • rdev:指向rpmsg设备的指针
  • name:与端点关联的服务名称
  • src :端点的本地地址
  • dest:端点的目标地址
  • cb :端点回调
  • ns_unbind_cb:当远程ept被销毁时,端点服务解除绑定回调。
返回值
  • 成功,返回RPMSG_SUCCESS
  • 失败,返回RPMSG_ERR_PARAM、RPMSG_ERR_ADDR

错误码说明:

  • RPMSG_ERR_ADDR,ept、rdev、cb是空指针。

  • RPMSG_ERR_PARAM,rdev地址越界或不可用。

备注

1.1.1.8 rpmsg_destroy_ept

void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);

销毁rpmsg端点并从rpmsg设备注销

参数
  • ept:指向要销毁的RPMsg终端的指针
返回值
备注

1.1.1.9 rpmsg_virtio_init_shm_pool

void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool, void *shbuf, size_t size);

初始化默认共享缓冲池,RPMsg-virtio具有默认的共享缓冲池实现。分配给该池的内存将专用于RPMsg-virtio。 在调用rpmsg_init_vdev以初始化rpmsg_virtio_shm_pool结构之前,必须调用此函数。

参数
  • shpool :指向共享缓冲池结构的指针
  • shbuf :指向共享缓冲区开头的指针
  • size : 共享缓冲区总大小
返回值
备注

1.1.1.10 rpmsg_init_vdev

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);

初始化rpmsg virtio设备。 主机侧: 初始化RPMsg-virtio队列和共享缓冲区,shm的地址可以是ANY。在这种情况下,函数将从系统共享内存池中 获取共享内存。如果vdev具有RPMsg名称服务功能,则此API将创建名称服务端点。 远程侧: 在主机端设置驱动程序就绪之前,此API不会返回。

参数
  • rvdev :指向rpmsg virtio设备的指针
  • vdev:指向virtio设备的指针
  • ns_bind_cb:用于名称服务通告的回调处理程序,无需本地端点等待绑定。
  • shm_io :指向共享内存I/O区域的指针
  • shpool:指向共享内存池的指针
返回值
  • 成功,返回RPMSG_SUCCESS
  • 失败,返回RPMSG_ERR_PARAM、RPMSG_ERR_NO_BUFF

错误码说明:

  • RPMSG_ERR_NO_BUFF,共享内存池内存分配失败。

  • RPMSG_ERR_PARAM,rvdev、vdev、shm_io是空指针。

备注

1.1.1.11 rpmsg_deinit_vdev

void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev);

取消对rpmsg virtio设备的初始化。

参数
  • rvdev :指向rpmsg virtio设备的指针
返回值
备注

1.1.1.12 rpmsg_virtio_get_rpmsg_device

static inline struct rpmsg_device *rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev);

从RPMsg-virtio设备获取RPMsg设备

参数
  • rvdev :指向rpmsg virtio设备的指针
返回值
  • 指向rpmsg virtio设备的指针rvdev
备注

1.1.2 remoteproc接口

1.1.2.1 remoteproc_init

struct remoteproc *remoteproc_init(struct remoteproc *rproc, struct remoteproc_ops *ops, void *priv));

创建和初始化remoteproc实例

参数
  • rproc:指向remoteproc实例的指针
  • ops:指向remoteproc操作的指针
  • priv:指向私有数据的指针
返回值
  • 创建remoteproc指针,表示成功
  • NULL,表示失败
备注

1.1.2.2 remoteproc_remove

int remoteproc_remove(struct remoteproc *rproc);

删除remoteproc实例

参数
  • rproc:指向remoteproc实例的指针
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败成功
  • errno
    • -RPROC_EINVAL:无效参数
    • -RPROC_EAGAIN:重试
备注

1.1.2.3 remoteproc_config

int remoteproc_config(struct remoteproc *rproc, void *data);

初始化remoteproc资源并加载和执行镜像

参数
  • rproc :指向remoteproc实例的指针
  • data :配置数据
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败
  • errno
    • -RPROC_EINVAL:无效参数
备注

1.1.2.4 remoteproc_start

int remoteproc_start(struct remoteproc *rproc);

从内存中已经存在的镜像入口启动远程处理器

参数
  • rproc:指向remoteproc实例的指针
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败
  • errno
    • -RPROC_EINVAL:无效参数
    • -RPROC_ENODEV:没有这样的设备
备注

1.1.2.5 remoteproc_stop

int remoteproc_stop(struct remoteproc *rproc);

停止远程处理器但不释放资源

参数
  • rproc:指向remoteproc实例的指针
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败
  • errno
    • -RPROC_ENODEV:没有这样的设备
备注

1.1.2.6 remoteproc_load

int remoteproc_load(struct remoteproc *rproc, const char *path, void *store, struct image_store_ops *store_ops, void **img_info);

从内存中已经存在的镜像入口启动远程处理器属性

参数
  • rproc:指向remoteproc实例的指针
  • path:镜像文件的可选路径
  • store:指向用户定义的图像存储参数的指针
  • store_ops:指向图像存储操作的指针
  • img_info:指向存储所使用图像信息的内存的指针
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败
  • errno
    • -RPROC_EINVAL:无效参数
    • -RPROC_ENODEV:没有这样的设备
备注

1.1.2.7 remoteproc_shutdown

int remoteproc_shutdown(struct remoteproc *rproc);

关闭远程处理器并释放资源

参数
  • rproc
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败
  • errno
    • -RPROC_ENODEV:没有这样的设备
备注

1.1.2.8 remoteproc_create_virtio

struct virtio_device *remoteproc_create_virtio(struct remoteproc *rproc,
					 int vdev_id, unsigned int role,
					 void (*rst_cb)(struct virtio_device *vdev));

创建virtio设备实例

参数
  • rproc:指向remoteproc实例的指针
  • vdev_id:virtio设备ID
  • role:virtio设备角色
  • rst_cb:virtio设备重置回调
返回值
  • 指针指向已创建的virtio设备,表示成功
  • NULL,表示失败
备注

1.1.2.9 remoteproc_remove_virtio

void remoteproc_remove_virtio(struct remoteproc *rproc, struct virtio_device *vdev);

删除virtio设备

参数
  • rproc:指向remoteproc实例的指针
  • vdev:指向virtio设备的指针
返回值
备注

1.1.2.10 remoteproc_add_mem

void remoteproc_add_mem(struct remoteproc *rproc, struct remoteproc_mem *mem)

添加remoteproc内存

参数
  • rproc:指向remoteproc实例的指针
  • mem:指向remoteproc内存的指针
返回值
备注

1.1.2.11 remoteproc_get_io_with_name

struct metal_io_region *remoteproc_get_io_with_name(struct remoteproc *rproc, const char *name);

通过指定内存名称的remoteproc获取内存libmetal I/O区域

参数
  • rproc:指向remoteproc实例的指针
  • name:共享内存的名称
返回值
  • metal I/O 区域指针,表示成功
  • NULL,表示失败
备注

1.1.2.12 remoteproc_get_io_with_pa

struct metal_io_region *remoteproc_get_io_with_pa(struct remoteproc *rproc, metal_phys_addr_t pa);

通过指定物理地址的remoteproc获取内存libmetal I/O区域

参数
  • rproc:指向remoteproc实例的指针
  • pa:物理地址
返回值
  • metal I/O 区域指针,表示成功
  • NULL,表示失败

1.1.2.13 remoteproc_get_io_with_va

struct metal_io_region *remoteproc_get_io_with_va(struct remoteproc *rproc, void *va);

通过指定虚拟地址的remoteproc获取内存libmetal I/O区域

参数
  • rproc:指向remoteproc实例的指针
  • va:虚拟地址
返回值
  • metal I/O 区域指针,表示成功
  • NULL,表示失败
备注

1.1.2.14 remoteproc_mmap

void *remoteproc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa, metal_phys_addr_t *da, size_t size, unsigned int attribute, struct metal_io_region **io);

映射内存并将内存添加到remoteproc实例

参数
  • rproc:指向remoteproc实例的指针
  • pa:物理地址指针
  • da:设备地址指针
  • size:内存的大小
  • attribute:内存属性
  • io:指向I/O区域的指针
返回值
  • metal I/O 区域指针,表示成功
  • NULL,表示失败
备注

1.1.2.15 remoteproc_set_rsc_table

int remoteproc_set_rsc_table(struct remoteproc *rproc, struct resource_table *rsc_table, size_t rsc_size);

解析并设置remoteproc的资源表

参数
  • rproc:指向remoteproc实例的指针
  • rsc_table:指向资源表的指针
  • rsc_size:资源表的大小
返回值
  • 返回0,表示成功,
  • 返回负值,表示失败成功
  • errno
    • -RPROC_EINVAL:无效参数
备注

1.2 规格说明

核间通信第三方库openamp的实现:

  • 已经实现了rpmsg组件、virtIO组件、libmetal库、UIO库、libsysfs库。

  • proxy组件的性质不属于功能,而是对rpmsg的封装而已,暂未实现该组件。

  • remoteproc需要芯片SDK支持,暂未实现该组件。

image

1.2.1 rpmsg组件规格

CPU 绑定:

rpmsg-sample-ping程序绑定于core0,rpmsg-sample-echo程序绑定于core1,完成不同核之间的消息处理。

1.2.2 virtIO 组件规格

1.2.3 Libmetal 组件规格

LiteOS-A新增eventfd接口,用以支持Libmetal处理主线程与irq线程之间的通信。

1.2.4 libsysfs 组件规格

libsysfs主要用于读取设备信息,由于LiteOS-A中没有sysfs,并且openamp中设备信息只用到uio0和uio1。 因此对使用libsysfs组件的相关代码逻辑进行适配,不从sysfs读取设备信息,而是直接指定uio0或uio1。

1.2.5 UIO组件规格

1.2.5.1 设备接口

系统增加了2个uio设备,并实现了对应的设备驱动。

设备 作用
/dev/uio0 用于访问共享内存
/dev/uio1 用于操作核间中断

可通过命令行查看到单板这个2个设备。

ls /dev
-rwxrwxrwx 0        u:0     g:0     uio1
-rwxrwxrwx 0        u:0     g:0     uio0

1.2.5.2 新定义IPI中断向量

新定义1个IPI中断,专门用于主核与从核之间的核间中断通知。

#define LOS_MP_IPI_NOTIFY 15

1.2.5.3 内核预留2MB共享内存

内核预留了物理内存最末端的2M,作为主核与从核的共享内存。用户调用mmap接口时,最多映射内存不得大于2MB。

共享内存起始地址的计算方式:物理内存起始地址 + 物理内存大小 - 2MB = (DDR_MEM_ADDR + SYS_MEM_SIZE_DEFAULT) - 2MB = (0x87f00000 - 0x200000) = 0x87d00000

#define DDR_MEM_ADDR  0x80000000
#define SYS_MEM_SIZE_DEFAULT 0x7f00000

#define DDR_MEM_AMP_SHM_SIZE    200000 //(2 * 1024 * 1024)
#define DDR_MEM_AMP_SHM_ADDR    DDR_MEM_ADDR + SYS_MEM_SIZE_DEFAULT - DDR_MEM_AMP_SHM_SIZE

1.2.5.4 新增核间中断的demo app

添加了核间中断的2个demo app, rpmsg-sample-pingrpmsg-sample-echo

完成了对libsysfs库解耦,不再依赖和解析libsysfs特有的文件设备信息,改为通过入参中dev name的字符串,判断访问设备uio0还是设备uio1

  • rpmsg-sample-ping

    • 通过openamp框架发送消息(绑定于core0)
  • rpmsg-sample-echo

    • 通过openamp框架接收消息(绑定于core1)

    • rpmsg-sample-echo在系统启动时,自动运行。

      对系统启动的配置脚本:vendor/hisilicon/hispark_taurus/init_configs/init_liteos_a_3516dv300.cfg,做了如下修改:

      jobs的init部分增加自动启动命令start rpmsg-sample-echo

	{
		"name" : "init",
		"cmds" : [
			"start apphilogcat",
			"start hiview",
			"start deviceauth_service",
			"start sensor_service",
			"start ai_server",
			"start softbus_server",
			"start rpmsg-sample-echo"
		]
	}
service部分增加启动的配置。
	{
		"name" : "rpmsg-sample-echo",
		"path" : ["/bin/rpmsg-sample-echo", "-L", "auto"],
		"uid" : 4,
		"gid" : 4,
		"once" : 1,
		"importance" : 0,
		"caps" : []
	}

1.3 新增加编译宏控制

增加了新的编译宏KERNEL_AMP,在这个宏之下,包括两个编译宏,依赖于该宏。

  • KERNEL_PRIMARY_CORE - 对应于主核

  • KERNEL_SECONDARY_CORE - 对应于从核

config KERNEL_AMP
	bool "Enable Kernel AMP"
	default n
	help
	  This option will enable amp support of LiteOS.

config KERNEL_PRIMARY_CORE
	bool "Enable Kernel Primary Core"
	default n
	depends on KERNEL_AMP
	help
	  This option will enable primary core support of LiteOS.

config KERNEL_SECONDARY_CORE
	bool "Enable Kernel Secondary Core"
	default n
	depends on KERNEL_AMP
	help
	  This option will enable secondary core support of LiteOS.  

2 系统资源开销

  • 系统内存中占用2MB作为共享内存

  • 系统中新增2个设备/dev/uio0/dev/uio1,作为主核与从核通信所用的UIO设备

  • 系统中的15号中断占用,作为IPI中断

1
https://gitee.com/rtos_yuan/project-delivery-and-archiving.git
git@gitee.com:rtos_yuan/project-delivery-and-archiving.git
rtos_yuan
project-delivery-and-archiving
项目交付归档
master

搜索帮助