“零”智享|TDA4 IPC核间通信原理

您所在的位置:网站首页 rpmsg文件 “零”智享|TDA4 IPC核间通信原理

“零”智享|TDA4 IPC核间通信原理

#“零”智享|TDA4 IPC核间通信原理| 来源: 网络整理| 查看: 265

目前很多芯片都会有几个core核,有的是Cortex M0+、M4、M7、A53、A73等等,有的有着2核、3核、4核甚至6核8核,不同的核的主频支持度不一样,适用的具体应用场景也不同,因此需要IPC(Inter-processor communication)来核间通信,进行数据的交互。

「IPC核间通信介绍」

核间通信(IPC)的主要目标是:充分利用硬件提供的机制,实现高效的CORE间通信;给需要CORE间通信的应用程序提供简洁高效的编程接口。

根据所使用的硬件特性,核间通信的实现机制有:

·Mailbox中断

·基于共享内存的消息队列

(通用的IPC通信流程)

「TDA4 IPC通信介绍」

Jacinto 7 SoC 在一个 SoC 上有多个不同的 CPU。包括 R5F、A72、C7x、C6x。在这些 CPU 上运行的软件需要相互协作并实现用例。协作方式通常被称为处理器间通信或IPC。每个 CPU 和操作系统上都提供了 IPC 库,以允许更高级别的应用程序相互通信。

IPC 的主要软件组件是:

TI-RTOS的PDK IPC LLD驱动,包括RPMSG、VRING和HW Mailbox驱动。

Linux内核IPC驱动套件,由RPMSG CHAR、RPMSG、VRING和HW Mailbox驱动组成。

(不同CPU/OS上的整体IPC SW堆栈)

RPMSG and VRING

RPMSG 是 Linux 和 TI-RTOS 使用的通用消息传递框架。RPMSG 是一种基于端点的协议,其中服务器 CPU 可以运行一个服务来侦听专用端点处的传入消息,而所有其他 CPU 可以向该(服务器 CPU、服务端点)元组发送请求。可以将其类比为网络中的 UDP/IP 层,其中 CPU 名称类似于 IP 地址,端点类似于 UDP 端口号。

虽然 RPMSG 是应用程序所见的 API 或协议,但在内部,IPC 驱动程序使用 VRING 在不同(RPMSG CPU、端点)元组之间实际传递消息。VRING 是一个共享内存段,位于一对 CPU 之间,用于保存两个 CPU 之间传递的消息

(RPMSG 端点与 VRING 的关系)

客户端 CPU / 任务在向服务器发送消息时还提供回复端点,以便服务器可以将其回复到客户端 CPU。

通过使用多个端点,可以在同一组 CPU 之间打开多个逻辑 IPC 通信通道。

(消息从发送方传递到接收方并再次返回的事件序列)

封装-VRING-解析的过程:

1、应用程序向给定目的地(CPU、端点)发送消息

2、消息首先从应用程序复制到两个CPU之间使用的VRING。此后,IPC 驱动程序在硬件邮箱中发布 VRING ID。

3、这会触发目标 CPU 上的中断。在目标 CPU 的 ISR 中,它提取 VRING ID,然后根据 VRING ID 检查该 VRING 中的所有消息。

4、如果收到消息,它从VRING中提取消息并将其放入目标RPMSG端点队列中。然后触发在此 RPMSG 端点上阻止的应用程序。

5、应用程序处理接收到的消息,并使用相同的RPMSG 和VRING 机制在相反方向回复发送方CPU。

Hardware Mailbox

硬件邮箱主要用于提供具有小的 32 位有效负载的中断事件通知。

VRING 使用硬件邮箱在目标 CPU 上触发中断。每个邮箱包含 16 个单向 HW 队列,最多可连接 4 个通信用户或 CPU。

J721E SoC 有 12 个硬件邮箱实例。即 12x 16 个硬件邮箱队列。

(硬件邮箱的逻辑框图)

Mailbox and VRING

邮箱本质上充当一个非常小的硬件队列,其中包含 VRING ID。

VRING 是共享内存中的 SW 队列,保存两个 CPU 之间传递的实际消息。当收到中断时,邮箱消息会告知从哪个 VRING 出列消息。

VRING ID=0 tells to look at the VRING from sender to receiver

VRING ID=1 tells to look at the VRING from receiver to sender

「编写IPC应用程序」Linux端IPC应用程序

在 linux 中,rpmsg 字符驱动程序由内核初始化,它为每个远程 rpmsg_chrdev 服务创建一个用户空间 /dev 条目。

obj->tx_fds[i] = appIpcCreateTxCH(i,prm->tiovx_rpmsg_prot_id,&host_port_id,&obj->rcdev[i]);

应用程序就有了一个可以用来读写消息的fd。

具体的应用代码可以参考

ti-processor-sdk-rtos-j721e-evm-08_01_00_13\vision_apps\utils\ipc\src

我们只需要将IPC的应用程序封装成库,供connector中间件调用即可。

接收函数:

memset(playroad,0,sizeof(payroad));

status = read(

obj->tx_fds[i],

payroad,sizeof(payroad));

if(status > 0)

{

appIpcRpmsgRxHandler(

i,

发送函数:

status=write(obj->tx_fds[dest_cpu_id],&payload,sizeof(payload));

if(status < 0 || status !=sizeof(payload))

{

appLogPrintf("IPC:TX:FAILED:%s ->%s (port %d) msg = 0x%08x\n",

appIpcGetCpuName(appIpcGetSelfCpuId()),

appIpcGetCpuName(dest_cpu_id),

(unit32_t)prot_id,

通过IPC核间通信达成数据交互,使得多核可以传输信息,共同协作,提高工作效率。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3